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

I'm new here... Being a former C++ programmer I started off
with PERL a year ago and I really like it now,
even though I didn't in the beginning.
Very well, One of these days I got really confused about
how PERL treats floats. If i write the simple code:

#!/usr/bin/perl -w #============= START PROGRAM ======================== $p_R = .1;<BR> for( $Go_R = 0.0; $Go_R < 7; $Go_R += $p_R) {#------------------------------------ FOR $Go_R print "Go_R = $Go_R\n";<BR> }#-------------------------------- END FOR $Go_R #=============== END PROGRAM ========================
I will get the "ending" output:
...
Go_R = 5.8
Go_R = 5.9
Go_R = 5.99999999999999
Go_R = 6.09999999999999
Go_R = 6.19999999999999
Go_R = 6.29999999999999
Go_R = 6.39999999999999
Go_R = 6.49999999999999
Go_R = 6.59999999999999
Go_R = 6.69999999999999
Go_R = 6.79999999999999
Go_R = 6.89999999999999
Go_R = 6.99999999999999

That is, I get a roundoff error VERY soon.
Why is that. This doesn't happen if I write the same kind of code in C++...

Replies are listed 'Best First'.
Re (tilly) 1: Strange concerning floats
by tilly (Archbishop) on Nov 07, 2001 at 22:43 UTC
    First of all it is Perl, not PERL.

    Secondly, Perl treats floats just like C does. The difference is that it is constantly going one way in the above code, and you are printing a higher resolution.

    Try using a printf to format your output to something less than one part in a hundred trillion accuracy, and see how much longer it takes for the round-off error to become visible.

Re: Strange concerning floats
by kwoff (Friar) on Nov 07, 2001 at 22:58 UTC
    I tested with C, and got a similar result if I used 'float' while I got a less-rounded result if I used 'double', so I guess perl does it with floats is the reason for the roundoff.
    #include <stdio.h> int main() { float d, f; d = 0.1; for (f = 0.0; f < 7; f += d) { printf("f = %f\n", f); } return 0; } $ ./precision-test ... f = 2.500000 f = 2.600000 f = 2.700000 f = 2.799999 f = 2.899999 ...
    (then if I change float to double, it's all 6.900000, etc..)
Re: Strange concerning floats
by Fastolfe (Vicar) on Nov 08, 2001 at 00:26 UTC
    This happens because computers do not store numbers internally in base-10, they store it in binary (base-2). Math operations require the computer to convert the operands to binary, do the math, and then convert back. So you may occasionally find some operations that give you slightly unexpected results like this. It's not a problem with the implementation, it's a problem with the numeric precision you're using (either the data type or the formatting of the output). In Perl you don't have much control over the data type (though the use of Math::BigFloat might help, but that's probably overkill), but you do have control over the formatting.