[fpc-pascal] Currency and ABS(-674.59)
Jonas Maebe
jonas.maebe at elis.ugent.be
Tue Mar 6 16:11:38 CET 2012
On 06 Mar 2012, at 13:28, michael.vancanneyt at wisa.be wrote:
> As far as I know, Currency is always a scaled int64, and didn't
> interpret the
> request as a request to change that.
The problem is that on i386 (and in Delphi on i386), operations on the
currency type are handled using the fpu. The result is that until
truncation (which only happens when storing the value to memory), you
can have rounding errors in the intermediate results. The fpu on other
platforms has not enough precision to exactly represent the entire
int64 range, so there we implement the currency type using an actual
int64 and with int64 arithmetic instead. Hence you don't get rounding
errors in intermediate results there.
> I missed probably part of the
> argumentation but on the face of it, having a ABS(Currency) seems
> like a
> reasonable request.
And also division for currency then, I guess (interestingly, the
program below also gives an error on non-x86 and win64 platforms
currently, but that's due to a code generation bug rather than a
rounding error -- the result from the second calculation is currently
completely bogus there):
var
c: currency;
begin
c:=(high(int64) div 10000) + 0.0333;
writeln(c/10.0);
writeln(c*(1/10.0));
if (c/10.0) <> c*(1/10.0) then
writeln('error');
end.
Output on Linux/i386:
$ ./curr2
9.223372036854770330E+13
9.223372036854770330E+13
error
Kylix also gives an error here, although it prints lets digits for the
writeln.
Anyway, my point is: a currency type implemented using floating point
math is basically a contradiction in terms, and no amount of duct tape
can fix that (except for storing the result to memory after every
single calculation, which would kill pretty much any speed advantage
that using the FPU could offer). So I'd prefer not to start adding
duct tape, since that's "een straatje zonder einde" :)
Jonas
More information about the fpc-pascal
mailing list