81.4 is evil

I know many of you all know pretty well that floating point precision and computers don’t play nicely with each other. I think I learned about it in the first book on ‘C’ I ever read, but I had never really been bitten by it until today. I was working with a piece of code today at the office that was throwing an error saying two values weren’t zeroing out when they clearly should have been. I narrowed down the problem and after a bit of time decided that 81.4 is a terrible, terrible number. For example:

<?php
$total = 100 - 81.4;
//$total should be 18.6
echo "18.6 == {$total}? " .
    ($total == 18.6 ? 'yes' : 'no') .
    "\n";
var_dump(18.6 - $total);
?>

So, let that be a lesson to us all. No matter how simple the calculation, don’t blindly trust floats.

Share
This entry was posted in PHP. Bookmark the permalink.

7 Responses to 81.4 is evil

  1. As any other guy I knew about floating point precision, but I always thought that it could only lose precision in the least significant digits, numerous digits after the decimal point and that it would only happen in inextricably complicated and rare situations. Now that I’ve run your very small and simple snippet I’m blown off.

    Thanks for sharing that insightful piece of information, now you’ve increased my paranoia by at least 7.105427357601E15 percents ;-)

  2. same here:
    $total = 100 – 81.3;
    print (18.7 – $total);

    or here:
    $total = 100 – 80.2;
    print (19.8 – $total);

    even in VB.

  3. Regin says:

    Rounding the values kinda sorts the problem … but yes it is really bad :/

  4. alex debril says:

    use the bcmath library : [url]http://www.php.net/manual/en/ref.bc.php[/url]

    $truetotal = (float) bcadd('100', '-81.4', 1);

    echo "18.6 == {$truetotal}? " .
            ($truetotal === 18.6 ? 'yes' : 'no') .
            "\n";

    var_dump(18.6 - $truetotal);

    output => 18.6 == 18.6? yes

  5. If you don’t have the bcmath php extension installed work out the values in cents first.

  6. Paul Meagher says:

    I’ve ported a part of the Weka Data Mining Utils class that is used in all the classes when numerical comparisons are made. It addresses your concerns by adding a tolerance factor to all comparisons.

    Here is a link to the relevant blog entry:

    http://www.phpmath.com/home?op=perm&nid=53

    Comments currently turned off as I don’t have time right now to deal with spambots.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>