为什么我在x64架构上获得以下输出?
$ php -r 'echo pow(2, 33) . "\n";print_r(unpack("Ivalue", pack("I", pow(2, 33))));'
8589934592
Array
(
[value] => 0
)
似乎它可以处理带符号的64位整数,但它无法打包/解包它们。根据文档http://us3.php.net/pack,我的大小应该取决于机器,在这种情况下是64位。
$ php -r 'echo PHP_INT_MAX;'
9223372036854775807
$ php -v
PHP 5.2.9 (cli) (built: Apr 17 2009 03:29:14)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies
答案 0 :(得分:2)
这是一个将任意大小的整数值打包成N位的函数:
function encode_int($in, $pad_to_bits=64, $little_endian=true) {
$in = decbin($in);
$in = str_pad($in, $pad_to_bits, '0', STR_PAD_LEFT);
$out = '';
for ($i = 0, $len = strlen($in); $i < $len; $i += 8) {
$out .= chr(bindec(substr($in,$i,8)));
}
if($little_endian) $out = strrev($out);
return $out;
}
这是一个解码压缩整数的函数:
function decode_int(&$data, $bits=false) {
if ($bits === false) $bits = strlen($data) * 8;
if($bits <= 0 ) return false;
switch($bits) {
case 8:
$return = unpack('C',$data);
$return = $return[1];
break;
case 16:
$return = unpack('v',$data);
$return = $return[1];
break;
case 24:
$return = unpack('ca/ab/cc', $data);
$return = $return['a'] + ($return['b'] << 8) + ($return['c'] << 16);
break;
case 32:
$return = unpack('V', $data);
$return = $return[1];
break;
case 48:
$return = unpack('va/vb/vc', $data);
$return = $return['a'] + ($return['b'] << 16) + ($return['c'] << 32);
break;
case 64:
$return = unpack('Va/Vb', $data);
$return = $return['a'] + ($return['b'] << 32);
break;
}
return $return;
}
答案 1 :(得分:0)
pack("I")
请求一个整数,对于x86_64上的I32LP64模型,它通常仍然是32位宽 - 至少在C中。解释器经常在顶部添加自己的定义。
答案 2 :(得分:0)
没有64位版本的PHP 5.2。第一个64位版本是Windows端的5.3.0的实验版本。因此,如果您在Windows上使用5.2.9,则必须至少升级到5.3.0才能获得64位版本。
如果我的前提是正确的,并且您在Windows上使用PHP,那么这就是它无法正常工作......
为了能够访问CPU的64位组件,整个堆栈必须是64位。这意味着CPU必须支持64位,操作系统必须支持64位,而应用程序必须支持64位。如果其中任何一个使用32位,则整个堆栈将从该点开始为32位。它是最低的共同点。
答案 3 :(得分:0)
因为pack将第二个参数作为字符串并将其转换为32位int。就比特大小的限制而言,唯一的解决方案是无符号的。看一下源代码,我看到很快就会出现一个64位版本的Perl,它使用'Q'来强制使用64位机器端。