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注意ef的变化):

var_dump('115f-401' == '115f-402');

我只能推测编译器将字符串视为大指数,并且比较太大而无法正确计算(115e-401115e-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中的字符串比较奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

奇怪的 Python 日期比较行为

奇怪的PHP字符串整数比较和转换

比较 Flutter web 中的两个字符串/比较两个 Cloud Firestore 对象的 documentID

AFNetworking 中的奇怪编码行为

比较未定义和错误的非常奇怪的行为

双重比较的C ++非常奇怪的行为[关闭]