上周末我改变了网站的webhosts。我所使用的主机服务器是32位操作系统,我移动的主机服务器是64位操作系统。出乎意料的是,我的一些PHP脚本开始提供不正确的结果。
在我的情况下<<和>> (位移)操作是罪魁祸首。我最终不得不用0xFFFFFFFF掩盖结果,然后改变结果,如果它为负,它就像以前一样工作。
我的PHP脚本中是否还有其他可能出现的问题?
答案 0 :(得分:6)
这是一种高级语言,所以任何非位相关的(位运算符,位移)都是相同的。
答案 1 :(得分:4)
整数可以是64位而不是32位。有一些奇怪的cases,这可能会导致问题。
答案 2 :(得分:2)
在C中,<<和>>通过使用 unsigned 变量可以使操作变得可移植,这会删除负数的1 / twos赞美规则。
作为一般规则,不要使用固定长度的掩码进行位操作(如&和|)。这些都取决于架构。
EG。重置最后4位: 掩码0xF0将工作在8位 架构,但不是16位。结果将是不同的(16位可能具有未设置在掩码中的其他位)。
要解决此问题,请使用〜运算符。掩码~0xF等效于0xF0,但可以在任何架构上工作。除最后4位之外的所有位都将被重置
答案 3 :(得分:2)
strtotime在64位上表现不同。来自PHP.net:
注意:
时间戳的有效范围通常是从星期五,1901年12月13日20:45:54 UTC到星期二,2038年1月19日03:14:07 UTC。 (这些是与32位有符号整数的最小值和最大值相对应的日期。)此外,并非所有平台都支持负时间戳,因此您的日期范围可能不会早于Unix时期。这意味着,例如1970年1月1日之前的日期不适用于Windows,某些Linux发行版和一些其他操作系统。 PHP 5.1.0和更新的版本克服了这个限制。
对于64位版本的PHP,时间戳的有效范围实际上是无限的,因为64位可以代表任何方向上大约2930亿年。
我们的代码正在执行strtotime('0000-00-00'),并且预期结果为false,当我们移动到64位时,我们得到了一个负整数。
答案 4 :(得分:1)
当您依赖32位二进制数据表示时,您将看到的唯一问题。 主要是因为PHP使用有符号整数,你会看到哈希,密钥生成等问题...当用(int),数字>显式地转换为int时除非它们是> 2,否则2 ^ 32将包裹它们将不会在64位环境中包裹的位置。当然是2 ^ 64。
4 vs 8 bit示例:
十进制值问题:
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 ]
所有整数/浮点运算将被视为64位值,因此如果您的最终结果依赖于32位块,则必须对此进行补偿。
答案 5 :(得分:0)
浮点除法的结果将受到增加到64位的影响;因此,如果您的代码执行某些愚蠢的操作,例如将浮点除法的结果与硬编码常量进行比较,那么期望它会中断。