HappyDeveloper
HappyDeveloper

Reputation: 12805

Problem with Floats! (in PHP)

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?

Upvotes: 2

Views: 9048

Answers (8)

Gekkie
Gekkie

Reputation: 1046

Just a minor addition for anywone looking:

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

Upvotes: 1

JimBeeUK
JimBeeUK

Reputation: 11

$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); 
    } 
?> 

Upvotes: 1

Gordon
Gordon

Reputation: 316939

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 =)'

Upvotes: 9

Ray
Ray

Reputation: 396

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) ...

Upvotes: 2

crdx
crdx

Reputation: 1432

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

Upvotes: 2

SubniC
SubniC

Reputation: 10317

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

Upvotes: 2

Sebastian Hoitz
Sebastian Hoitz

Reputation: 9373

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.

Upvotes: 2

Lucas Moeskops
Lucas Moeskops

Reputation: 5443

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 :)

Upvotes: 4

Related Questions