I think that the reason is type conversions. Abs()
function returns real
results, so currency
variable casts to real
. Take a look at documentation:
Currency is a fixed-point data type that minimizes rounding errors in
monetary calculations. On the Win32 platform, it is stored as a scaled
64-bit integer with the four last significant digits implicitly
representing decimal places. When mixed with other real types in
assignments and expressions, Currency values are automatically divided
or multiplied by 10000.
so Currency is fixed and real is floating-point.
Sample code for your question is :
program Project3;
{$APPTYPE CONSOLE}
const VALUE = 0.09;
var a,b : currency;
begin
a := VALUE;
b := VALUE;
if a = Abs(b) then writeln('equal')
else writeln('not equal', a - Abs(b));
readln;
end.
produces not equal result, because of type conversions;
compiler watch reveals the same value for abs(vtemp1) and vtemp2
Try to add x : real
, then call x := abs(b);
, add x
to watches list, select it and press Edit watch
, then select Floating point. X
becomes 0.899...967
.
not only 0.09
value produces such result. you can try this code to check:
for i := 0 to 10000 do begin
a := a + 0.001;
b := a;
if a <> abs(b) then writeln('not equal', a);
end;
so, if you need absolute value of Currency variable - just do it. don't use floating-point abs()
:
function Abs(x : Currency):Currency; inline;
begin
if x > 0 then result := x
else result := -x;
end;