繁体   English   中英

在Bitwise Operations中PHP的Infinit值返回奇怪的值

[英]PHP's Infinit value in Bitwise Operations returns strange values

今天我刚刚做了一个有趣的发现,同时测试了在PHP中按比例计算的内容,如INF ^ 0^ => Bitwise运算符的异或(XOR)),这给了我int(-9223372036854775808) =>最大可能的负值64-比特系统。

但后来我问自己:“为什么当”正无限“意味着9223372036854775807 (63位在1上有前导0 )和0(64位在0 => 0 xor 0 = 0 )时,结果在XOR中变为负数虽然是PHP的无限值,它背后的计算是什么?当我使用“负无限”时,为什么我得到一个(正确的?)负值(0 => 1 xor 0 = 1前导1对前导0 ? ”。

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

按位运算

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

编辑:相应于jbafford,获得完整的答案会很棒,所以我只是引用他: why does 5.5 and 5.6 result in PHP_INT_MIN, and everything else return 0?

首先, ^本身不是什么特别的。 如果你对零的异或,或者任何零的异或,你只需要回到原来的答案。 你在这里看到的不是操作本身的一部分,而是操作之前发生的事情:按位运算符采用整数,因此PHP将浮点数转换为整数。 它是浮点到整数转换中出现的奇怪行为,并且它不是按位运算符所独有的。 例如,它也适用于(int)

为什么会产生这些奇怪的结果呢? 只是因为在将float转换为整数时,这就是编写PHP代码所产生的代码。 在C标准中,对于INF-INFNAN的特殊值, 未定义 C的浮点到整数转换的行为(或者更确切地说,对于“整数部分”,整数不能表示: §6.3.1.4 ) 。 这种未定义的行为意味着编译器可以随意做任何事情。 在这种情况下恰好发生它生成的代码在这里产生最小整数值,但不能保证总是会发生,并且它在整个平台或编译器中不一致。 1为什么行为在5.4和5.5之间变化? 因为用于将浮点数转换为整数的PHP代码更改为始终执行模数转换 这种固定的不确定的行为非常大的浮点数,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 * 2PHP_INT_MIN * 2 ),则结果未定义。 PHP 5.5使结果保持一致,但不直观(如果将float转换为非常大的整数,则会起作用,并且丢弃最高有效位)。

你的float(INF)被隐式地转换为Integer。

和0的XOR不会改变第一个参数。 所以基本上这只是一个从float到int的转换,对于不在整数范围内的值是未定义的。 (对于所有其他值,它将被截断为零)

https://3v4l.org/52bA5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM