php中的字符串比较奇怪的行为
Posted
技术标签:
【中文标题】php中的字符串比较奇怪的行为【英文标题】:String comparation strange behavior in php 【发布时间】:2021-09-07 10:34:18 【问题描述】:今天我在比较 2 个不同的字符串时发现了非常奇怪的行为
dd('115e-401' == '115e-402');
这是返回true
。但是为什么呢?;
【问题讨论】:
我猜(未经测试)它将这些字符串视为非常大的数字,因为它假设e-401
是 401 阶的指数。比较像这样的两个巨大数字可能超出了php能够
感谢您的解释
当使用严格比较 (===
) 这不是问题。
【参考方案1】:
当字符串看起来是数字时,类型杂耍开始。
如果两个操作数都是数字字符串,或者一个操作数是数字而另一个是数字字符串,则以数字方式进行比较。
E-401 是一个非常小的数字,比 PHP 所能表示的要小。最小的数字是PHP_FLOAT_MIN
大约为 2.2E-308(取决于系统)。
因此,您的字符串将转换为数字。它们比 PHP 可以表示的要小,并被转换为零。 0 == 0 为真。
【讨论】:
【参考方案2】:快速测试以下在 PHP 中返回 true
:
var_dump('115e-401' == '115e-402');
然后确认这会返回false
(注意e
到f
的变化):
var_dump('115f-401' == '115f-402');
我只能推测编译器将字符串视为大指数,并且比较太大而无法正确计算(115e-401
和115e-402
是非常小的数字)。注意:感谢@Tobias K 指出错误指出这些是 large 而不是 small 数字!
如果您想正确比较字符串,请改用严格的类型比较(即===
或strcmp
):
var_dump('115e-401' === '115e-402'); // false
var_dump(strcmp("115e-401","115e-402")); // A non-zero value
strcmp
将返回一个非零值 - 表示它们不相等。在这种情况下,结果 0 表示相等。
注意:澄清strcmp
的结果将非零,表示在@u_mulder 的有用反馈之后值不相等。
【讨论】:
数字很小,不是很大(负指数),但你的答案的本质是正确的,它超出了精度。 @TobiasK。谢谢你的收获,在我的匆忙中,我没有停下来思考!我已经澄清,事实上,现在答案中的数字非常小var_dump(strcmp("115e-401","115e-402"));
将返回 -256:3v4l.org/5ktbs
@u_mulder 我已修改答案以反映非零答案表示字符串不同,因为我无法解释为什么我在一个编译器上看到 -1 而在另一个编译器上看到 -256 .然而,只有 0 的结果表示相等这一事实有望成为这种情况下的主要事实。感谢您指出这一点
这也是 C 中的 UB。您得到的唯一确定性是 0 - 具体值可以只是 -1 或实际上是“差异范围”,具体取决于实现(我假设 PHP 在这里仅依赖于 libc)。只需检查这些条件(==0 或!=0),而不是 ==-1。或者使用 strict ===
来比较字符串。以上是关于php中的字符串比较奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章