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?

3

9 Answers 9

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

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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.

Comments

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

Comments

2

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

Comments

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

Comments

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

Comments

1

Just a minor addition for anywone looking:

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

Comments

0

You can use serialize_precision setting.

ini_set('serialize_precision',-1); 

which uses enhanced rounding.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.