Php -0不等于0
我有一个计算值的函数,它是一个浮点:Php -0不等于0,php,floating-point,Php,Floating Point,我有一个计算值的函数,它是一个浮点: function crunch (float $a, float $b):float { //do stuff return $result; } function testSomething (float $a, float $b):bool { //if $result is -0 that returns false $result = crunch($a, $b); return $result === 0; } 为什么-0不
function crunch (float $a, float $b):float
{
//do stuff
return $result;
}
function testSomething (float $a, float $b):bool
{
//if $result is -0 that returns false
$result = crunch($a, $b);
return $result === 0;
}
为什么-0不等于0,如果假设0
应该与-0
相同,如何安全地检查该数字是否为零
更新
因为有更多细节的问题。我有一个类Vec2
,它有x()
和y()
getter,还有一个名为cross
的方法,看起来像这样:
public function cross(Vec2 $vec2):float
{
return ($this->_x * $vec2->_y) - ($vec2->_x * $this->_y);
}
运行此代码:
$cross = $this->cross($d);
结果是调试器输出
而
$cross==0
的计算结果为false
将0强制转换为浮动。它可能会失败,因为0作为literal是一个int,而结果是一个float,因此===因类型而为false
至少这样做会像你的案例一样失败(结果是错误的):
在这种情况下,结果是正确的:
php -r '$a = (float) -0; $b = (float) 0; echo ($a == $b);'
函数float_equiv(float$a、float$b、float$epsilon=NULL){
//默认为PHP配置的显示精度
$epsilon=$epsilon?:pow(10,-1*ini_get('precision');
if(绝对值($a-$b)<$epsilon){
返回true;
}
返回false;
}
仅用@monstercode来说明公认的答案
数学逻辑和计算机逻辑是分离的实体。
我们直观地知道-0=0,但在计算机术语中,数字的符号是与数字分开存储的(就像元数据一样)——这就是浮点数的作用
在这种情况下,将整数与浮点进行比较
$result_1 = 1234*0;// remains an integer
$result_2 = -1234*0;// remains an integer
$result_3 = -1.234*0;// becomes a float
$result_4 = 1.234*0; // becomes a float
var_dump($result_1 === 0); // true
var_dump($result_2 === 0); // true
var_dump($result_3 === 0); // false
var_dump($result_4 === 0); // false
作为旁注。。不应该是
float$a,float$b
而不是float$a,float$b
当然!它已经更新了…你能更详细地了解一下结果是如何生成的或者看起来是什么样的吗<代码>-0不是一件事,这是真的:var\u dump(-0==0)代码>是的,我正要说,0是int而不是float:D你需要(float)0比较♥ PHP!我永远不会<代码>预设值
是一个可能的输入错误,应该是精度
,不正确吗?第三次才是魅力所在。^的确如此;-)很好的测试,但是这个测试与类型转换和0有关。
与0
完全不同,至少在PHP逻辑中是这样。噢,很好的捕获。我更喜欢较短的语法,而不是类型转换<代码>0。$floatvalue==0。
计算结果为true!所有的注意力都集中在结尾的
上,没错。我更喜欢0.0或0.00,在我看来这是更自然的阅读,.0
也会。它只是一个定义的浮动。小心浮点数的字符串连接。
function float_equiv(float $a, float $b, float $epsilon=NULL) {
// default to PHP's configured display precision
$epsilon = $epsilon ?: pow(10, -1*ini_get('precision'));
if( abs($a - $b) < $epsilon ) {
return true;
}
return false;
}
$result_1 = 1234*0;// remains an integer
$result_2 = -1234*0;// remains an integer
$result_3 = -1.234*0;// becomes a float
$result_4 = 1.234*0; // becomes a float
var_dump($result_1 === 0); // true
var_dump($result_2 === 0); // true
var_dump($result_3 === 0); // false
var_dump($result_4 === 0); // false