Yet another person who needs to be reminded that floating point can't represent most decimal values exactly? Note the following about the two numbers that exhibit your problem:
printf "%.20f\n", 1.667695;
printf "%.20f\n", 1.000695;
__END__
1.66769499999999990000
1.00069499999999990000
So, I'm not surprised that those don't get rounded up to end in "70", since they are each less than 1.___695. They are as close to 1.___695 as the chosen floating point representation can get, but they are almost always going to be just above or just below and so how they round has to do with whether they can be more closer approximated by an n/2**p that is just above the desired value or just below the desired value.
Now, Perl has been playing more and more tricks about ignoring the last bit or two if it would result in "0000001" or "9999999" to more effectively hide this fact from more people (in part because they tend to complain when they first discover it). It appears that perhaps your Perl 5.008_005 has added one more such trick (or gotten a bit more aggressive with an existing trick), though my Perl 5.008_008 agrees with both of our Perls 5.006_001.
An interesting pattern is that pretty consistently about 72.5% of the numbers round as one would expect and only about 27.5% round lower due to this floating point short-coming. Update: I finally varied enough parts to find a bunch of ranges with 53% "normal" and 47% "low" or 85% "normal" and 15% "low"...
Perl's being "smart" is a bit annoying here because Perl used to be more easily more useful for getting an understanding of this stuff. For example, perl4's output for my sample program is:
1.66769499999999993000
1.00069499999999989000
which gives us more information about how close the floating point values are able to get to our desired values. This also gives us a clue as to why the second number has "the problem" for both of your Perls while the first doesn't; the second is not as close. Update: And, I suspect that my sample program run on your Perl 5.008_005 will give 5 trailing zeros in the output unlike the 4 trailing zeros I got with my Perls v5 and the 3 trailing zeros I got with Perl4.
|