Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the result of RoundTo(87.285, -2) => 87.28

Tags:

delphi

I expected that the result would be 87.29. I also tried SimpleRoundTo, but produces the same result.

In the help there is also a "strange" example: ms-help://embarcadero.rs2010/vcl/Math.RoundTo.html

RoundTo(1.235, -2) => 1.24
RoundTo(1.245, -2) => 1.24 //???

Does anybody know which function I need to get the result of 87.29? I mean: If the last digit >= 5 round up, if < 5 round down. As taught in the school :)

I use Delphi2010, and SetRoundMode(rmNearest). I also tried with rmTruncate. The value 87.285 is stored in a double variable.

Also strange:

SimpleRoundTo(87.285, -2) => 87.29

but

x := 87.285; //double
SimpleRoundTo(x, -2) => 87.28
like image 627
markus_ja Avatar asked Mar 04 '11 08:03

markus_ja


2 Answers

The exact value 87.285 is not representable as a floating-point value in Delphi. A page on my Web site shows what that value really is, as Extended, Double, and Single:

87.285 = + 87.28500 00000 00000 00333 06690 73875 46962 12708 95004 27246 09375
87.285 = + 87.28499 99999 99996 58939 48683 51519 10781 86035 15625
87.285 = + 87.28500 36621 09375

By default, floating-point literals in Delphi have type Extended, and as you can see, the Extended version of your number is slightly higher than 87.285, so it is correct that rounding to nearest would round up. But as a Double, the real number is slightly lower. That's why you get the number you expected if you explicitly store the number in a Double variable before calling RoundTo. There are overloads of that function for each of Delphi's floating-point types.

like image 128
Rob Kennedy Avatar answered Nov 17 '22 18:11

Rob Kennedy


87.285 is not exactly representable and the nearest double is slightly smaller.

The classic reference on floating point is What Every Computer Scientist Should Know About Floating- Point Arithmetic.

For currency based calculations, if indeed this is, you should use a base 10 number type rather than base 2 floating point. In Delphi that means Currency.

like image 21
David Heffernan Avatar answered Nov 17 '22 19:11

David Heffernan