【问题标题】:32 to 64 bit "Gotchas" in PHPPHP 中的 32 到 64 位“陷阱”
【发布时间】:2010-09-28 16:54:32
【问题描述】:

上周末我为我的网站更换了虚拟主机。我使用的主机服务器是 32 位操作系统,而我移动到的主机服务器是 64 位。出乎意料的是,我的一些 PHP 脚本开始给出不正确的结果。

在我的例子中,>(位移)操作是罪魁祸首。我最终不得不用 0xFFFFFFFF 掩盖结果,然后如果结果为负,则更改结果以使其像以前一样工作。

我的 PHP 脚本中是否还有其他可能的问题我应该寻找?

【问题讨论】:

  • 你到底在做什么用位移位?我问是因为我想知道是否一些“优化”尝试只是回来咬你。
  • 不,这不是优化。它是混合用户名和日期以确定用于解锁程序的用户密钥的代码。见:beholdgenealogy.com/blog/?p=656

标签: php 32bit-64bit


【解决方案1】:

它是一种高级语言,因此任何与位无关的(按位运算符、位移位)都是相同的。

【讨论】:

    【解决方案2】:

    整数可能是 64 位而不是 32 位。有一些奇怪的cases 可能会导致问题。

    【讨论】:

      【解决方案3】:

      位操作需要特别小心才能在系统/架构之间移植。

      在 C 语言中,> 操作可以通过使用 unsigned 变量来实现可移植性,这消除了负数的一/二补码规则。

      作为一般规则,不要使用固定长度的掩码进行位操作(如 & 和 |)。这些是依赖于架构的。

      例如。重置最后 4 位: 掩码 0xF0 将在 8 位上工作 架构,但不是 16 位。结果会有所不同(16 位可能有其他未包含在掩码中的位设置)。

      要解决这个问题,请使用 ~ 运算符。掩码 ~0xF 等价于 0xF0,但适用于 any 架构。除了最后 4 位之外的所有位都将被重置

      【讨论】:

        【解决方案4】:

        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') 并期望结果为假,当我们移动到 64 位时,我们得到一个负整数。

        【讨论】:

          【解决方案5】:

          当您依赖数据的 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 ]
          

          所有整数/浮点运算都将被视为 64 位值,因此如果您的最终结果依赖于 32 位块,您将不得不对此进行补偿。

          【讨论】:

            【解决方案6】:

            增加到64位会影响浮点除法的结果;因此,如果您的代码执行了一些愚蠢的操作,例如将浮点除法的结果与硬编码常量进行比较,那么预计它会中断。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-12-28
              • 2019-01-07
              • 1970-01-01
              • 2018-12-29
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多