gpt4 book ai didi

PHP 在按位运算中的 Infinit 值返回奇怪的值

转载 作者:IT王子 更新时间:2023-10-29 00:13:02 26 4
gpt4 key购买 nike

今天我在测试 php 中按位计算的情况时有一个有趣的发现,例如 INF ^ 0 (^ => 异或 (XOR) 的按位运算符) 什么给了我 int(-9223372036854775808) => 64 位系统中最大可能的负值。

但后来我问自己:“当“正无限”表示 9223372036854775807(1 上的 63 位,前导 0) and 0 (64 Bits on 0 => 0 xor 0 = 0) 什么是 PHP 的无限值,它背后的计算是什么?为什么当我使用“negative infinit”时我会得到一个(正确的?)负值(A leading 1 against a leading 0 on 0 => 1异或 0 = 1?"。

另一个有趣的点是,这只发生在 PHP 版本 5.5.9-1 上,而不是例如在 5.3.x 上和 5.6.x(我已经测试过)!也许有人知道那里会发生什么?在三个版本上对其进行了测试,但只有我的 (5.5.9-1) 给出了这些结果:

Bitwise operations

只是想让你们知道,这只是我为了好玩而做的抽象游戏,但我发现它很有趣。也许有人可以在这里提供帮助或向我解释我的错误想法?如果有人需要有关任何事情的更多信息,请告诉我!

编辑:根据 jbafford 的说法,如果能得到一个完整的答案会很棒,所以我只引用他的话:为什么 5.5 和 5.6 会导致 PHP_INT_MIN,而其他所有内容都返回 0?

最佳答案

首先,^ 本身并不是这里的特殊之处。如果你用零异或任何东西,或者用零或任何东西,你只会得到原来的答案。您在这里看到的不是操作本身的一部分,而是操作之前发生的事情:按位运算符采用整数,因此 PHP 将 float 转换为整数。奇怪的行为出现在 float 到整数的转换中,并且它不是按位运算符所独有的。例如,(int) 也会发生这种情况。

为什么会产生这些奇怪的结果?仅仅是因为这就是 PHP 编写的 C 代码在将 float 转换为整数时产生的内容。在 C 标准中,对于 INF-INF 的特殊值,C 的浮点到整数转换行为是未定义 NAN(或者更准确地说,对于“整数部分”,整数不能表示:§6.3.1.4)。这undefined behaviour意味着编译器可以自由地做任何它想做的事。在这种情况下,它生成的代码会在此处产生最小整数值,但并不能保证总是会发生这种情况,而且跨平台或编译器也不一致。1为什么行为会发生变化在 5.4 和 5.5 之间?因为PHP将 float 转换为整数的代码changed to always perform a modulo conversion .这修复了非常大的 float 2 的未定义行为,但它仍然没有检查特殊值,因此对于这种情况,它仍然产生未定义的行为,只是这次略有不同。

在 PHP 7 中,我决定使用 Integer Semantics RFC 清理这部分 PHP 行为。 ,这使得 PHP 检查特殊值(INF-INFNAN)并一致地转换它们:它们总是转换为整数 0。这里不再有未定义的行为。


1 例如,我用 C 编写的测试程序试图将 Infinity 转换为整数(特别是 C long)在 32 位和64 位构建。 64 位版本始终生成 -9223372036854775808,这是最小整数值,而 32 位版本始终生成 0。这种行为对于 GCC 和 clang 是相同的,所以我猜他们都生成非常相似的机器代码。

2 如果您尝试将 float 转换为整数,而该 float 的值太大而无法放入整数(例如 PHP_INT_MAX * 2,或 PHP_INT_MIN * 2),结果未定义。 PHP 5.5 使结果一致,但不直观(如果 float 被转换为非常大的整数,并且最高有效位被丢弃,它就会起作用)。

关于PHP 在按位运算中的 Infinit 值返回奇怪的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34904642/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com