题
上周末,我改变了主机管理我的网站。我是在主机服务器是一个32位操作系统和我移动到一个是64位的。没想到,我的一些PHP脚本的开始给不正确的结果。
在我的情况下<<和>>(比特移位)操作是罪魁祸首。我结束了具有掩盖为0xFFFFFFFF的结果,然后改变的结果,如果负为它工作,因为它没有前。
有没有在我的PHP脚本任何其他可能出现的问题,我应该寻找什么?
解决方案
这是一个高级语言,所以任何非位相关(位运算符,位位移)将是相同的。
其他提示
位操作,需要特别注意使系统/体系结构之间移植的。
在C,<<和>>操作可以通过使用由便携式无符号变量,其去除的那些/负数二进制补码的规则。
作为一般的规则,不使用用于位操作的固定长度的掩模(如&和|)。这些是体系结构相关。
EG。复位后4位:中 面膜0XF0将在8位工作 架构,而不是16位。结果将是不同的(16位可具有不包含在所述掩模被设置其它位)。
要克服这个问题,利用〜运算符。掩模〜0xF相当于0XF0,但对任何架构将工作。除了最后4中的所有位将被重置
的strtotime表现不同的64位。从PHP.net:
注意:
的时间戳的有效范围通常为星期五,1901年12月13日20时45分54秒到UTC星期二,2038年1月19日3点14分07秒UTC。 (这些是对应于最小和最大值为32位带符号整数的日期。)此外,并非所有平台都支持负的时间戳,因此日期范围可以被限制为不大于Unix时间戳早。这意味着,例如之前的1970年1月1日日期将不会在Windows,一些Linux发行版,以及其他一些操作系统上运行。 PHP 5.1.0及更新的版本克服了此限制,但。
有关PHP的64位版本,时间戳的有效范围是有效地无限的,如64个比特可以表示大约293十亿年任一方向。
我们不得不说是做的strtotime代码(“0000-00-00”)和预期的结果是假的,当我们转移到64位,我们将得到一个负整数。
唯一的问题就是你看到的是,当你依赖于数据的32位二进制表示。 主要是因为PHP使用符号整数,你会看到在散列,密钥生成,问题等等时明确铸造用(INT)为int,数字> 2 ^ 32将包裹在那里,他们将无法在64位环境包裹除非它们是> 2 ^ 64当然。
4对8位的示例:
十进制值的问题:
0010 >> 1 = 0001 [ 1 dec ]
0000 0010 >> 1 = 0000 0001 [ 1 dec ]
这些都产生相同的结果(十进制明智),但是:
0100 << 1 = 1000 [ -8 dec ]
0000 0100 << 1 = 0000 1000 [ 16 dec ]
包装的问题:
1000 << 1 = 0000 [ 0 dec ]
0000 1000 << 1 = 0001 0000 [ 32 dec ]
所有整数/浮点OPS将被视为64比特的值,因此,如果您的最终结果依赖于32位块,你将不得不补偿这样的
浮点除法的结果将通过增加到64位受到影响;所以如果你有代码,做一些愚蠢像浮点除法的结果比较硬编码的常数,期望它打破。