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