Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Fun with floating points

by kikuchiyo (Monk)
on Nov 06, 2009 at 13:36 UTC ( #805476=perlmeditation: print w/ replies, xml ) Need Help??

I've got bitten by a peculiarity of floating point handling recently.

The phenomenon is best illustrated with the following snippet:
$ perl -le'$x=0.05;$y=sqrt($x+$x+$x);$g="$y";print "Is $y equal to $g? +";print $y==$g?"Yes":"No"' Is 0.387298334620742 equal to 0.387298334620742? No

Of course there is nothing surprising here after all. It should just serve as a reminder that floating point numbers are nasty beasts. It is dangerous to have certain assumptions about them. Also, when you write code that processes a lot of numbers then forms decisions based on comparisons ofthem, it is important to check that the code really does what you think it does. Extreme cases, loss of accuracy and so on.

Comment on Fun with floating points
Download Code
Re: Fun with floating points
by Fox (Pilgrim) on Nov 06, 2009 at 14:23 UTC
    I think this is not a problem with float point numbers, but with the comparison operator:
    perl -le'$x=0.05;$y=sqrt($x+$x+$x);$g="$y";print "Is $y equal to $g?"; +print $y eq $g?"Yes":"No"' Is 0.387298334620742 equal to 0.387298334620742? Yes
      I had a reason to post it as I did.

      In the actual application where I had this issue, the workflow was something like this: data was read off from data files and stored in a Storable file. Later, these Storable files were retrieved, and the data in them was further processed. And finally I used a numerical comparison to get the result (is the number dug up from the Storable archives bigger than a pre-specified limit). However, Storable stores floating point numbers as text, at least it did in my application.

      So the real issue here is that it is awesomely convenient to have scalars-that-are-both-numbers-and-strings in Perl, but one has to be careful and know that it may lead to strange results sometimes.
        String/float conversion is not the only problem while dealing with floats. Consider following example:
        perl -e '$x=1/3; $x-=1/2; $x+=1/3; $x-=1/2; $x+=1/3; print $x,"\n"'
        $x should be equal to zero but it isn't.
Re: Fun with floating points
by lostjimmy (Chaplain) on Nov 06, 2009 at 17:22 UTC
    You should really be comparing floating point numbers using a threshold, rather than an absolute comparison. The problem in your code (correct me if I'm wrong) is that the representation changed when converting from a string back to a float. The following demonstrates a better way to do this.
    my $x = 0.05; my $y = sqrt($x+$x+$x); my $g = "$y"; my $h = sprintf "%.20f", $y; printf "\$y = %.20f\n\$g = %.20f\n", $y, $g; printf "\$h = %.20f\n", $h; print "Is \$y equal to \$g? ", floatEqual($y, $g) ? "Yes\n" : "No\n"; print "Is \$y equal to \$h? ", $y == $h ? "Yes\n" : "No\n"; sub floatEqual { return (abs($_[0] - $_[1]) <= 10**15); }

    I also added the $h variable, which works just fine in a direct comparison. I'm sure someone else who knows more about internal representations and conversions can shed more intelligent light on this.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://805476]
Approved by moritz
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (10)
As of 2014-09-30 22:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (385 votes), past polls