Here is a Perl script:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my @numbers = qw(
0.254
0.255
0.256
);
foreach my $number (@numbers) {
my $rounded = sprintf '%.2f', $number;
say "$number => $rounded";
}
foreach my $number (@numbers) {
$number += 100;
my $rounded = sprintf '%.2f', $number;
say "$number => $rounded";
}
It outputs:
0.254 => 0.25
0.255 => 0.26
0.256 => 0.26
100.254 => 100.25
100.255 => 100.25
100.256 => 100.26
For me it is very strange that Perl is inconsistent with rounding. I expect that both number ending with .255 to be rounded as .26 It is true for 0.255, but it is false for the number 100.255.
Here is the quote from Perl Cookbook, http://docstore.mik.ua/orelly/perl/cookbook/ch02_04.htm,
sprintf . 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.
But I can't see any evidence that it is correct in http://perldoc.perl.org/functions/sprintf.html
Is it a bug in sprintf or Perl Cookbook is wrong? If it is desired behaviour, why does it work this way?
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);
sprintf() function in Perl uses Format provided by the user to return the formatted string with the use of the values in the list. This function is identical to printf but it returns the formatted string instead of printing it.
If you add this line:
$number = sprintf '%.15f', $number;
before printing, you will have:
0.254000000000000 => 0.25
0.255000000000000 => 0.26
0.256000000000000 => 0.26
100.254000000000005 => 100.25
100.254999999999995 => 100.25
100.256000000000000 => 100.26
as you can see, 100.255
is not exactly 100.255
this is due to representation of float numbers.
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