in reply to When is a 2 not a 2?

Change your the print to
printf "%.16e\n", $x;
and you get
1.0000000000000000e+000 1.1000000000000001e+000 1.2000000000000002e+000 1.3000000000000003e+000 1.4000000000000004e+000 1.5000000000000004e+000 1.6000000000000005e+000 1.7000000000000006e+000 1.8000000000000007e+000 1.9000000000000008e+000 Stop: x=2.0000000000000009e+000 No, x is not 2.

1/10 is a periodic number in binary, just like 1/3 is a periodic number in decimal.

You'll get better results if you avoid accumulating the error:

for ( 1*10 .. 2*10 ) { my $x = $_/10; printf "%.16e\n", $x; }
1.0000000000000000e+000 1.1000000000000001e+000 1.2000000000000000e+000 1.3000000000000000e+000 1.3999999999999999e+000 1.5000000000000000e+000 1.6000000000000001e+000 1.7000000000000000e+000 1.8000000000000000e+000 1.8999999999999999e+000 2.0000000000000000e+000

Basically, introduce decimal numbers as late as possible. For example, work with cents instead of dollars.

Replies are listed 'Best First'.
Re^2: When is a 2 not a 2?
by Argel (Prior) on Jan 31, 2008 at 00:50 UTC
    That's a good explanation and sound advice. So, is there any harm in doing "$x" ne "2"? Or would it be better to use sprintf "%.02f", $x to convert it?

      So, is there any harm in doing "$x" ne "2"?

      When, to end the loop? It'll work for this loop. What about longer loops? The loop counter would accumulate more and more error, potentially skewering your numbers and potentially making the loop into an infinite loop. Seems to me to be plain bad practice to knowingly accumulate an error.