-0不等于0

时间:2018-03-08 18:42:49

标签: php floating-point

我有一个计算值的函数,它是一个浮点数:

const result = await parse(<somebody>)

为什么 -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课程,其Vec2x()获取者,以及一个名为y()的方法,看起来像这样:

cross

运行此代码:

public function cross(Vec2 $vec2):float
{
  return ($this->_x * $vec2->_y) - ($vec2->_x * $this->_y);
}

导致调试器输出

enter image description here

$cross = $this->cross($d); 评估为$cross === 0;

3 个答案:

答案 0 :(得分:5)

将0转换为float。它可能失败了,因为0作为文字是一个int,结果是一个浮点数,所以===因为类型而为假。

至少做这样的事情,就像你的情况一样失败(结果是假的):

php -r '$a = (float) -0; $b = 0; echo ($a === $b);'

在这种情况下结果是正确的:

php -r '$a = (float) -0; $b = (float) 0; echo ($a == $b);'

答案 1 :(得分:4)

  1. 负零不是一回事。但是,小于浮点显示的配置精度的负值是。
  2. 您无法可靠地检查两个浮点数之间的直接等价,您只能合理地检查两个浮点数之间的差异是否小于您对给定计算的关注。
  3. 例如:

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

答案 2 :(得分:0)

只是为了说明@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