[fpc-pascal] Currency and ABS(-674.59)

Jonas Maebe jonas.maebe at elis.ugent.be
Sun Mar 4 23:22:37 CET 2012

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).


More information about the fpc-pascal mailing list