On 04 Mar 2012, at 22:31, Zaher Dirkey wrote:

> I found this problem in Delphi and FPC, please test it and confirm if it is
> a bug.

The problem is caused by the facts that
a) on i386, currency operations are calculated using the 80x87 floating point 
unit
b) there is no separate abs() for currency, hence abs(currency) becomes 
currency(abs(extended(currency)))

Conversion from currency to a floating point type means dividing by 10000 and 
converting back means multiplying again by 10000. The division by 10000 results 
in a rounding error, which in turn results in the unexpected comparison result 
(the result of the abs(currency) in your expression is not stored to memory, 
and hence still contains the full 80 bits of "precision" from the 
division/multiplication combo). That is why Jeppe's program works correctly: 
then the result is stored back into a variable, which hides the rounding error.

It's basically a property of the fact that on i386, currency is a floating 
point type handled by the fpu that emulates a fixed point type. This particular 
problem could obviously be resolved by adding a currency-specific version of 
abs(), but in general the problem can occur with several other expressions too 
(as soon as for one reason or another, the operation is not implemented 
specifically for currency and the compiler inserts a conversion to another 
floating point type).


Jonas_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to