2

What's wrong with php floats?

$v = 5.2 * 3;

if($v==15.6) {
    echo 'Everything is fine =)';
} else {
    echo 'Okay something is wrong :S';
    var_dump($v); // float 15.6
}

Check this out too:

$v = 5.2 * 3;

if($v>15.6 AND $v<15.60000000001) {
    echo 'We are doomed :S';
    var_dump($v); // float 15.6
} else {
    echo 'Everything is fine =)';
}

I guess it has something to do with the internal representation or some obscure low level stuff? If that's the case, how do I get around this issue? Anything else I should know before using this to calculate real money transactions?

mskfisher
  • 3,291
  • 4
  • 35
  • 48
HappyDeveloper
  • 12,480
  • 22
  • 82
  • 117

8 Answers8

9

I am sure this is a duplicate, so I'm making this a CW

$v = 5.2 * 3;
if (bccomp($v, 15.6) === 0) {
    echo 'Everything is fine =)';
} else {
    echo 'Okay something is wrong :S';
    var_dump($v); // float 15.6
}

will give 'Everything is fine =)'

Gordon
  • 312,688
  • 75
  • 539
  • 559
4

It has to do with the internal representation indeed :). Never compare float values. I think there will exists php classes/modules that work around this problem, but you can also store your money values as integers and multiply them by 100. Before display you can divide them again :)

Lucas Moeskops
  • 5,445
  • 3
  • 28
  • 42
2

This has to do with floats in general and is not limited to PHP.

When using floats you should check for intervals with a specific precision, just as you did in your last example:

if(abs($v - 15.6) < 0.0001)
{
    // Yey :)
}

You can run into a lot of problems when using exact values.

Sebastian Hoitz
  • 9,343
  • 13
  • 61
  • 77
2

the value you are getting is 15.600000000000001 and it is diferent to 15.6, this topic has been widely discussed, you can take a look to this threads:

HTH, Regards

Community
  • 1
  • 1
SubniC
  • 9,807
  • 4
  • 26
  • 33
2

The PHP page on floats has a warning against comparing for equality and also links to this page which links to bccomp.

crdx
  • 1,412
  • 13
  • 26
2

If you really need to compare floats check for being in bounds of an allowed deviation instead of an exact match, like

$DEVIATION = 0.0001;
if(abs($v-15.6)<$DEVIATION) ...
Ray
  • 396
  • 3
  • 10
1
$v = 5.2 * 3;

if((string)$v == "15.6") {
    print "yes";
}

It's always good to check PHP website as most developers have come across problems before PHP.net Floating Point Number this comment shows a function for comparing floats.

<?php 
    function IsFloatEqual($x,$y,$precision=0.0000001) 
    { 
        return ($x+$precision >= $y) && ($x-$precision <= $y); 
    } 
?> 
JimBeeUK
  • 11
  • 1
1

Just a minor addition for anywone looking:

the BC* functions are the only true way to work with floats in PHP!

Gekkie
  • 996
  • 9
  • 24