如何在 PHP 中测试负零?



在PHP中有一个浮点负零,尽管打印为不同的字符串,但它与浮点正零-0.0 === 0.0相同。PHP 中没有整数负零。

我正在编写舍入函数的扩展版本,并尝试尽可能多地复制PHP的本机行为。我正在使用TDD方法编写它,因此我需要一种方法来验证我的代码是否符合本机PHP函数,方法是返回负零,而PHP返回负零。

<?php
var_dump(ceil(-0.5));
double(-0)

除了以下情况之外,是否有任何方法可以测试-0.0

  • 将其转换为字符串(string)-0.0 === '-0'
  • 序列化它serialize(-0.0) === 'd:-0;'

@njuffa建议if (1 / $x === -INF),它有效,但会发出除以零警告。

@Manu-sh 通过使用新的"power of"运算符对其进行了修改以在没有警告的情况下执行相同的操作:**

<?php
function is_negative_zero($x) {
return $x ** -1 === -INF;
}
echo is_negative_zero(0.0)? "Yes": "No";
echo PHP_EOL;
echo is_negative_zero(-0.0)? "Yes": "No";
echo PHP_EOL;

输出:

No
Yes

仅适用于文字,不适用于变量:

var_export(0.0 ** 0 == 1);
var_export(-0.0 ** 0 == -1);

但这似乎也适用于变量:

// return 1 for positive zero, -1 for negative zero
// otherwise return 0
function zero_sign(float $x): int {
if (($y = ($x ** -1)) === -INF)
return -1;
return $y === INF;
}
var_export(zero_sign(-0.0) === -1);
var_export(zero_sign(0.0)  ===  1);
var_export(zero_sign(-1.0) ===  0);
var_export(zero_sign(1.0)  ===  0);

您可以自己检查这是否遵循数学规则, 以下是 -0.0 ** -1 和 0.0 ** -1 的Wolframalpha结果

浮点数有一个特定的位,如果它是负数,则在内部编码中设置。此测试也适用于区分 +0.0 和 -0.0。该测试还与 PHP 如何执行 -0.0 和 +0.0 的操作无关。

function isNegativFloat($value){
return is_float($value) AND ord(pack('E',$value)) & 0x80;
}

例子:

var_dump(isNegativFloat(0.0));  //bool(false)
var_dump(isNegativFloat(-0.0));  //bool(true)
var_dump(isNegativFloat(0.6));  //bool(false)
var_dump(isNegativFloat(-0.6));  //bool(true)

负浮点零点特殊测试:

function isNegativFloatNull($value){
return $value === 0.0 AND isNegativFloat($value);
}

例子:

var_dump(isNegativFloatNull(0.0));  //bool(false)
var_dump(isNegativFloatNull(-0.0));  //bool(true)
var_dump(isNegativFloatNull(0.6));  //bool(false)
var_dump(isNegativFloatNull(-0.6));  //bool(false)

最新更新