dechex()
函数PHP manual page的示例#2如下:
// 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
知道这里发生了什么?
答案 0 :(得分:0)
首先,重要的是要注意PHP dechex
函数需要整数输入。
在64位系统上,PHP不支持64位整数。
例如,64位系统上的典型PHP_INT_MAX
是:
9223372036854775807
这也是dechex
可以接受的最大整数(!)数。
如果传入pow(2, 64) - 1
,则转换为整数的浮点数(1.844674407371E+19
)为整数0
,因此dechex
返回字符串"0"
。
如果您将2 ^ 64作为字符串"18446744073709551615"
传入,则同样适用。它被转换为整数,在64位系统上它的整数值为9223372036854775807
。因此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";
答案 1 :(得分:0)
我怀疑在64位平台上有一个dechex的错误,这个错误与可存储为浮点数的最大整数是pow(2,53)-1,即9007199254740991这个事实有关。该手册确实警告过使用base_convert使用非常大的数字,因为你可以使用浮点数,并且浮点系统不精确的b / c可能会出现奇怪的结果。 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上提交错误报告。