Divide bug?

exeunt on 2003-03-11T19:07:43

I just sent this post to perl5-porters. This had me pulling my hair out as to what is causing it.

Below is a copy of the email I sent...

A co-worker of mine came across something strange that had me pulling my hair out. Below is an example of the bug in action. Logically you would think that if you divide 72.9 by 100, you get 0.729, so it should match the if statement. At first we thought it was because we had 0.729000 as the condition, but that doesn't matter. Also in the below code I have it test against 0.729 and 0.729000 without it resulting from a divide, and it passes.

I tested this against 5.005_03, 5.6.0, 5.6.1 and 5.8.0, all exhibit this behaviour.

#!/usr/bin/perl use warnings; use strict;

my $test = 72.9; my $divtest = $test/100; my $condition = 0.729; my $hardcode = 0.729000; print "divtest => $divtest\ncondition => $condition\n"; if ($divtest == $condition) { print "Should be true\n"; } elsif ($divtest == $hardcode) { print "This also should be true\n"; } else { print "What the?!!?\n"; } if ($condition == $hardcode) { print "Without divide it works\n"; }


UPDATE: Mark Jason Dominus set me straight, but as I just wrote back, I figured since their NV's are both 0.729 in the output from Devel:Peel, it would work... guess not, someone else replied directly to me and suggested using 'eq', but using that for numerical comparisons makes me feel a bit ill.


floating point numbers are only equal by luck

jmm on 2003-03-11T19:43:16

Floating point numbers are not exact, and they get more inexact as you work with them. (In Kernghan and Plauger, they say "floating point numbers are like piles of sand - every time you move the pile, you lose a bit of sand and pickup a bit of dirt".)

Instead of comparing for exact equality, check that they are relatively close. I.e. instead of:

if ( $x == 0.329 ) ...

use:

if( abs($x-0.329) 1e-7 ) ...

Re:floating point numbers are only equal by luck

exeunt on 2003-03-11T20:15:41

I get a syntax error, are you sure you got that right?

Re:floating point numbers are only equal by luck

bart on 2003-03-11T21:10:09

The < sign got dropped. This is HTML...

It's not just perl...

runrig on 2003-03-11T19:47:03

I had to explain this to a java programmer not long ago. Try this to see what's going on:
printf("%.20f\n", 72.9/100);

Re:It's not just perl...

exeunt on 2003-03-11T19:58:02

Yeah, MJD sent me another email in private with printf "%.40f", $f to see what is going on... :)

There's no such thing as 0.1!

merlyn on 2003-03-12T00:48:34

Amazingly enough, something as simple as 0.1 has no exact IEEE floating point representation!