On 06 Mar 2012, at 13:28, michael.vancann...@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

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

Reply via email to