Can someone explain why there is a difference in behavior here?
perl -E 'say sprintf("%.2f",5.555);'
5.55
perl -E 'say sprintf("%.2f",0.555);'
0.56
I have read that sprintf()
rounds up if the following digits is 5 or greater. So why doesn't it round up to 0.56 in the second case?
Note that the value returned by sprintf is rounded, due to the specified print format.
Use the Perl function sprintf, or printf if you're just trying to produce output: # round off to two places $rounded = sprintf("%. 2f"", $unrounded);
The f format lets you specify a particular number of decimal places to round its argument to. Perl looks at the following digit, rounds up if it is 5 or greater, and rounds down otherwise. Three functions that may be useful if you want to round a floating-point value to an integral value are int , ceil , and floor .
The closest IEEE 754 64-bit binary floating point number to 0.555 is 0.55500000000000004884981308350688777863979339599609375. It is very slightly closer to 0.56 than to 0.55.
The closest IEEE 754 64-bit binary floating point number to 5.555 is 5.55499999999999971578290569595992565155029296875. It is very slightly closer to 5.55 than to 5.56.
In each case, the output is the nearest decimal with 2 decimal places to the actual value of the internal number.
As Pascal Cuoq says in a comment, 0.555 is in the binade [0.5 … 1), in which representable floating-point numbers are separated by 2-53. By contrast, 5.555 is in the binade [4 … 8), in which representable floating-point numbers are separated by 2-50. That is why the fractional parts are different for 0.555 and 5.555.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With