I'm seeing some weird behavior in php when comparing a double to a string and was hoping someone could explain to me what is going on.
If I declare $num = 0.333; and then test $num == '0.333', this comes out as true. If I then add 1 to $num and then subtract 1, then $num == '0.333' comes out as false. If I then cast $num as a string, the comparison goes back to being true. Why is it doing this?
Here's a sample:
<?php
$num = 0.333;
//returns 0.333 double Yes
echo $num, ' ', gettype($num), ' ', $num == '0.333' ? 'Yes' : 'No', '<br />';
$num += 1;
$num = $num - 1;
//returns 0.333 double No
echo $num, ' ', gettype($num), ' ', $num == '0.333' ? 'Yes' : 'No', '<br />';
$str = (string)$num;
//returns 0.333 string Yes
echo $str, ' ', gettype($str), ' ', $str == '开发者_运维技巧0.333' ? 'Yes' : 'No', '<br />';
?>
Thanks.
You are comparing a floating point.
http://php.net/manual/en/language.types.float.php says:
never compare floating point numbers for equality.
The ==
compares for value, but 'across' types: one of the types must be converted before it can actually be compared. And this will result in comparison of floating point variables. That's why after doing a seemingly balanced action (+1 and -1) you're getting different results.
For comparing value AND type in PHP, you need to use 3 "=". like :
$num = 333
$num === 333 => true
$num === '333' => false
See here for more details http://php.net/manual/en/language.operators.comparison.php
A possible way to compare Float, is to use the method indicated in the comments of php.net regarding floats :
<?php
$number1=number_format($float1,2,'.','');
$number2=number_format($float2,2,'.''');
if($number1!=$number2){
echo 'do correction here!';
}
?>
But apparently, there isn't a definitive, best way to do it (or I didn't found it). Some convert the float to String, other does the code I just wrote.
As you like ;)
Take away point: use === instead of == to avoid type coercion.
The reason is that in the first instance $num is a double, but it is also equal to the string '0.333'.
Using === shows that the double 0.333 isn't the same as the string '0.333'.
The second one has done some addition, now the double isn't exactly 0.333 anymore, so it isn't the same as a string to to floating point inaccuracies.
The third one has cast 0.333 to a string, which is of course the same as the string.
To compare two float or double use http://php.net/manual/en/function.bccomp.php
You are comparing a float for which trailing digits are a problem.
One think you can do is convert the float to a string and take the first x characters (ie if you have a string '.333' that you're comparing it to, convert the float to a string and take the first four characters), or you can floor the float to the proper decimals before comparing it.
精彩评论