比较 php 中的浮点数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3148937/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Compare floats in php
提问by Santosh Sonarikar
I want to compare two floats in PHP, like in this sample code:
我想比较 PHP 中的两个浮点数,就像在这个示例代码中一样:
$a = 0.17;
$b = 1 - 0.83; //0.17
if($a == $b ){
echo 'a and b are same';
}
else {
echo 'a and b are not same';
}
In this code it returns the result of the elsecondition instead of the ifcondition, even though $aand $bare same. Is there any special way to handle/compare floats in PHP?
在这段代码中,它返回else条件的结果而不是if条件,即使$a和$b相同。有没有什么特殊的方法来处理/比较 PHP 中的浮点数?
If yes then please help me to solve this issue.
如果是,那么请帮我解决这个问题。
Or is there a problem with my server config?
还是我的服务器配置有问题?
回答by Joey
If you do it like this they shouldbe the same. But note that a characteristic of floating-point values is that calculations which seemto result in the same value do not need to actually be identical. So if $ais a literal .17and $barrives there through a calculation it can well be that they are different, albeit both display the same value.
如果你这样做,它们应该是一样的。但请注意,浮点值的一个特点是,看似产生相同值的计算实际上并不需要完全相同。因此,如果$a是文字.17并$b通过计算到达那里,则它们很可能不同,尽管两者都显示相同的值。
Usually you never compare floating-point values for equality like this, you need to use a smallest acceptable difference:
通常你永远不会像这样比较浮点值的相等性,你需要使用最小的可接受差异:
if (abs(($a-$b)/$b) < 0.00001) {
echo "same";
}
Something like that.
类似的东西。
回答by Andrey
Read the red warning in the manualfirst. You must never compare floats for equality. You should use the epsilon technique.
首先阅读手册中的红色警告。你永远不能比较浮点数是否相等。您应该使用 epsilon 技术。
For example:
例如:
if (abs($a-$b) < PHP_FLOAT_EPSILON) { … }
where PHP_FLOAT_EPSILONis constant representing a very small number (you have to define it in old versions of PHP before 7.2)
wherePHP_FLOAT_EPSILON是常量,代表一个非常小的数字(你必须在 7.2 之前的旧版本 PHP 中定义它)
回答by Mario
Or try to use bc math functions:
或者尝试使用 bc 数学函数:
<?php
$a = 0.17;
$b = 1 - 0.83; //0.17
echo "$a == $b (core comp oper): ", var_dump($a==$b);
echo "$a == $b (with bc func) : ", var_dump( bccomp($a, $b, 3)==0 );
Result:
结果:
0.17 == 0.17 (core comp oper): bool(false)
0.17 == 0.17 (with bc func) : bool(true)
回答by Michael Butler
As said before, be very careful when doing floating point comparisons (whether equal-to, greater-than, or less-than) in PHP. However if you're only ever interested in a few significant digits, you can do something like:
如前所述,在 PHP 中进行浮点比较(无论是等于、大于还是小于)时要非常小心。但是,如果您只对几个有效数字感兴趣,则可以执行以下操作:
$a = round(0.17, 2);
$b = round(1 - 0.83, 2); //0.17
if($a == $b ){
echo 'a and b are same';
}
else {
echo 'a and b are not same';
}
The use of rounding to 2 decimal places (or 3, or 4) will cause the expected result.
使用四舍五入到小数点后 2 位(或 3 或 4)将导致预期结果。
回答by FieryCat
It would be better to use native PHP comparison:
最好使用原生 PHP 比较:
bccomp($a, $b, 3)
// Third parameter - the optional scale parameter
// is used to set the number of digits after the decimal place
// which will be used in the comparison.
Returns 0 if the two operands are equal, 1 if the left_operand is larger than the right_operand, -1 otherwise.
如果两个操作数相等,则返回 0,如果 left_operand 大于 right_operand,则返回 1,否则返回 -1。
回答by Ame Nomade
If you have floating point values to compare to equality, a simple way to avoid the risk of internal roundingstrategy of the OS, language, processor or so on, is to compare the string representationof the values.
如果您有浮点值要与相等性进行比较,避免操作系统、语言、处理器等内部舍入策略风险的一种简单方法是比较值的字符串表示形式。
You can use any of the following to produce the desired result: https://3v4l.org/rUrEq
您可以使用以下任何一种来产生所需的结果:https: //3v4l.org/rUrEq
String Type Casting
字符串类型转换
if ( (string) $a === (string) $b) { … }
String Concatenation
字符串连接
if ('' . $a === '' . $b) { … }
strval function
strval 函数
if (strval($a) === strval($b)) { … }
String representations are much less finicky than floats when it comes to checking equality.
在检查相等性时,字符串表示比浮点数要少得多。
回答by dtbarne
If you have a small, finite number of decimal points that will be acceptable, the following works nicely (albeit with slower performance than the epsilon solution):
如果您的小数点数量有限且可以接受,则以下方法可以很好地工作(尽管性能比 epsilon 解决方案慢):
$a = 0.17;
$b = 1 - 0.83; //0.17
if (number_format($a, 3) == number_format($b, 3)) {
echo 'a and b are same';
} else {
echo 'a and b are not same';
}
回答by crmpicco
This works for me on PHP 5.3.27.
这在 PHP 5.3.27 上对我有用。
$payments_total = 123.45;
$order_total = 123.45;
if (round($payments_total, 2) != round($order_total, 2)) {
// they don't match
}
回答by Gladhon
For PHP 7.2, you can work with PHP_FLOAT_EPSILON ( http://php.net/manual/en/reserved.constants.php):
对于 PHP 7.2,您可以使用 PHP_FLOAT_EPSILON ( http://php.net/manual/en/reserved.constants.php):
if(abs($a-$b) < PHP_FLOAT_EPSILON){
echo 'a and b are same';
}
回答by Natalie Rey
Here is the solution for comparing floating points or decimal numbers
这是比较浮点数或十进制数的解决方案
//$fd['someVal'] = 2.9;
//$i for loop variable steps 0.1
if((string)$fd['someVal']== (string)$i)
{
//Equal
}
Cast a decimalvariable to stringand you will be fine.
将decimal变量投射到string,你会没事的。

