0

该函数的PHP 手册页的示例 #2如下:dechex()

// The output below assumes a 32-bit platform.
// Note that the output is the same for all values.
echo dechex(-1)."\n";
echo dechex(PHP_INT_MAX * 2 + 1)."\n";
echo dechex(pow(2, 32) - 1)."\n";

上面的示例将输出:

ffffffff
ffffffff
ffffffff

我正在尝试在 x64 系统上重现该行为:

echo dechex(-1)."\n";
echo dechex(PHP_INT_MAX * 2 + 1)."\n";
echo dechex(pow(2, 64) - 1)."\n";

我期待:

ffffffffffffffff
ffffffffffffffff
ffffffffffffffff

但是,我得到:

ffffffffffffffff
0
0

知道这里发生了什么吗?

4

2 回答 2

0

首先,重要的是要注意 PHPdechex函数需要整数输入。

在 64 位系统上,PHP 不支持 64 位整数。

例如,PHP_INT_MAX64 位系统上的典型情况是:

 9223372036854775807

这也是dechex可以接受的最大整数 (!) 数。

如果你传入pow(2, 64) - 1它是一个浮点数(1.844674407371E+19),它转换为整数是整数,0因此dechex返回字符串"0"

如果您将 2^64 作为 string 传递,同样适用"18446744073709551615"。它被转换为整数,它的整数值9223372036854775807在 64 位系统上。所以 dechex 返回字符串"7fffffffffffffff"

因此,如果您需要处理这些数字,则不能使用 PHP 的整数类型,因此dechex不是适合该工作的工具。相反,您可以使用 bcmath 和 gmp 函数来实现您正在寻找的内容:

echo gmp_strval(bcadd(bcmul(2, PHP_INT_MAX), 1), 16), "\n";
echo gmp_strval(bcsub(bcpow(2, 64), 1), 16), "\n";
于 2013-03-08T07:43:51.340 回答
0

我怀疑 64 位平台上的 dechex 存在一个错误,这与可以存储为浮点数的最大整数是 pow(2,53)-1 即 9007199254740991 这一事实有关。手册确实警告过使用非常大的带有 base_convert 的数字,因为您可以使用浮点数,并且由于浮点系统的不精确性,可能会出现奇怪的结果。dechex 可能会发生类似的情况。

PHP 接受一个数字作为 dechex 的参数,它可以是整数或浮点数,但实际上浮点数只是一种用于表示溢出 int 边界的整数的设备。事实是,您在 32 位平台上成功运行的代码也传递给 dechex 一个超过 32 位平台的最大整数值的值,传入一个浮点数,如下注释所示:

<?php

echo "Max int: ",PHP_INT_MAX, "\n"; // Max int: 2147483647
$num = (PHP_INT_MAX * 2) + 1;
var_dump($num);   //                // float(4294967295)
echo dechex($num),"\n";            // ffffffff
echo dechex(-1);                   // ffffffff

您可能希望在 bugs.php.net 提交错误报告。

于 2013-07-07T21:18:52.550 回答