First: the best wishes for 2004 to all of you.
I have a problem with decimals.
I have two variables of the type Double. During the program the first
variable (fBtw) has the value 1724.725 and the second variable (fBruto)
10802.225. Then I converts both variables to strings with Format('%.2f',
variable):
sfBtw := Format('%.2f', [fBtw]); // -> 1724.72
sfBruto := Format('%.2f', [fBruto]); // -> 10802.23
Why, o why converts Format .725 to .72 and .225 to .23 ????? I tried it
under WinNT and Win2000 with the same result.
Is there a better way to convert a double with more than 2 decimals to a
double with 2 decimals?
Bert Prins
I think you will find that 1724.725 is actually 1724.724999999999
The Double format uses the IEEE convention
- which has its 'features'
See the FAQ for more info :-
http://www.bancoems.com/CompLangPascalDelphiMisc-MiniFAQ.htm#Q3
I don't think that is the entire cause of the problem here. What is
happening is that the value is being rounded as it is converted to string. I
don't have access to the documentation at the moment, but if you look up the
formatting options, I believe that you will probably find that using "%.2f"
rounds the value to 2 decimal positions. To get three decimal positions, try
using "%.3f". To get the correct value, get a larger number of decimal
positions, 4 or 5, and then round to the appropriate number of decimals.
<snip>
>>
>> I think you will find that 1724.725 is actually 1724.724999999999
>>
>> The Double format uses the IEEE convention
>> - which has its 'features'
>>
>> See the FAQ for more info :-
>>
>> http://www.bancoems.com/CompLangPascalDelphiMisc-MiniFAQ.htm#Q3
>>
>
>I don't think that is the entire cause of the problem here. What is
>happening is that the value is being rounded as it is converted to string. I
>don't have access to the documentation at the moment, but if you look up the
>formatting options, I believe that you will probably find that using "%.2f"
>rounds the value to 2 decimal positions. To get three decimal positions, try
>using "%.3f". To get the correct value, get a larger number of decimal
>positions, 4 or 5, and then round to the appropriate number of decimals.
Well you are in for a nasty surprize
- try this - and pay particular attention to what N4 is reported as
procedure TForm1.Button1Click(Sender: TObject);
Var
N1, N2, N3, N4 :Double;
S :String;
begin
N1 := 3.244; //Down
N2 := 1.249; //Up
N3 := 2.2501; //Down
N4 := 1724.725; //Bad IEEE number
S := Format('%.2f', [N1] ) + #13
+ Format('%.2f', [N2] ) + #13
+ Format('%.2f', [N3] ) + #13
+ Format('%.15f', [N4] );
ShowMessage( S );
end;
Hello,
I do believe it may be Delphi's use of Banker's rounding. I quote from the
Pascal Newsletter #9 http://www.latiumsoftware.com/en/pascal/0009.php (only
because it was the first in my Google search that explains it and not in any
way as an endorsement):
"ROUNDING NUMBERS
The Round function that comes with Delphi performs what is called
"banker's rounding", meaning that a number with a fractional part of
0.5 is rounded sometimes up and sometimes down, always towards the
nearest even number. This means that for example Round(3.5) gives 4
while Round(2.5) gives 2."
HTH
Dot