alexg has asked for the wisdom of the Perl Monks concerning the following question:

Just came across this strange behaviour in a for loop. Could anyone explain? Or am I missing something obvious? Code:
for(my $x = 0; $x <= 0.1; $x += 0.001){ print "$x\n"; }
Outputs: (... and ???? added by me)
0 0.001 0.002 ...... 0.07 0.071 0.07200000000000001 (????) 0.07300000000000001 (????) .....
Is this a known bug in Perl? I'm using 5.6.1 on i386-linux

Replies are listed 'Best First'.
Re: For loop wierdness
by DrHyde (Prior) on Oct 08, 2003 at 13:20 UTC
    It's just rounding errors. You'll get the same in C and in any other language which doesn't support arbitrary precision floats. If it really matters to you, use Math::BigFloat.
Re: For loop wierdness
by Albannach (Monsignor) on Oct 08, 2003 at 13:33 UTC
    The good DrHyde is quite correct. Another alternative would be to use integers:
    for(my $x = 0; $x <= 100; ++$x){ print $x/1000,"\n"; }
    Your choice should depend on how much accuracy you really need, presuming that you will use $x in actual calculations, not just a list of values. I'd avoid the overhead of Math::BigFloat unless it was really necessary.

    --
    I'd like to be able to assign to an luser

Re: For loop wierdness
by Abigail-II (Bishop) on Oct 08, 2003 at 13:40 UTC
    $ perldoc -q decimal Found in /opt/perl/lib/5.8.1/pod/perlfaq4.pod Why am I getting long decimals (eg, 19.9499999999999) instead of the numbers I should be getting (eg, 19.95)? Internally, your computer represents floating- point numbers in binary. Digital (as in powers of two) computers cannot store all numbers exactly. Some real numbers lose precision in the process. This is a problem with how computers store numbers and affects all computer languages, not just Perl. perlnumber show the gory details of number repre- sentations and conversions. To limit the number of decimal places in your num- bers, you can use the printf or sprintf function. See the "Floating Point Arithmetic" for more details. printf "%.2f", 10/3; my $number = sprintf "%.2f", 10/3;

    Abigail