Am 03.07.2018 um 19:42 schrieb g...@wolfgang-ehrhardt.de:
Zitat von Vojtěch Čihák <vojtech.ci...@atlas.cz>:
will not give any warning even if correct result is 2.5.
It is simply absurd because it is not about shooting your own foot. Compiler is not a crystal ball, it does what you
tell him.
If you need floating point, use floating point types and floating point division (my example) and if you need signed
results, use
Really?
There are other source of loss of precision (in the trunk version) and the
compiler does
not what I tell him. Example:
const
d1: double = 1.0/3.0;
d2: double = 1/3;
x1: extended = 1.0/3.0;
x2: extended = 1/3;
s1: single = 1.0/3.0;
s2: single = 1/3;
begin
writeln(s1:30:10, s2:30:10);
writeln(d1:30:16, d2:30:16);
writeln(x1:30:16, x2:30:16);
end.
and the result
0.3333333433 0.3333333433
0.3333333432674408 0.3333333333333333
0.3333333432674408 0.3333333333333333
The single result is expected. But the double and extended constants d1, x1 are
evaluated as single, even if I told the compiler to use the floating point
quotient 1.0/3.0.
In pascal, the rule applies that *the resulting type of an operation does not depend on the type a value is assigned
too*. So: 1.0 fits perfectly into a single, 3.0 as well, they are single constants (you didn't tell the compiler
otherwise). Nobody wants that unnecessarily larger types are used. So for the compiler this is a single division and
later on the result is converted into extended. The result for integer is indeed a little bit strange, here probably the
default rule applies that any /-operand is converted to the best available real type if it is not a real type, thus the
result differs. Question is, if the compiler should look the operand types and choose more carefully the types, but I
tend more to say no.
If I use the integer quotient the values are as expected. This is against intuition
True, but intuition is bad in programming :)
and gives
no warning. And even if I can adapt to this and live with this quirk:
What is exactly the quirk?
Is there a definite
statement, that is will remain so.
Insert type casts for the constants to get proper results on all archs, see
below.
(Delphi works as expected).
The reason why delphi behaves different is probably due to it's roots in being x87 only: x87 does all calculations with
extended precision. You get similar trouble if you do multiple single operations in one statement and on x87, the result
is normally different from all other FPUs because x87 does not round in between. This is different from most other FPU
implementations. This can be fixed only with the price doing on all non-x87 FPUs floating point operations unnecessarily
precise.
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal