谁能告诉我,为什么我得到的x64架构以下输出:
$ PHP -r回响POW(2,33)。 \ N;的print_r(解包(Ivalue,包(我,POW(2,33))));
8589934592
排列
(
[值] => 0
)
这好像它可以处理64位签署整数,但不能包/解压它们。根据文档: http://us3.php.net/pack ,我的尺寸应机相关的,在此情况下为64bit。
感谢。
修改 应该在原来的职位提到了这一点:
$ PHP -r回响PHP_INT_MAX;
9223372036854775807
编辑2
$ PHP -v
PHP 5.2.9(CLI)(内置:2009年4月17号3点29分14秒)
版权所有(C)1997-2009 PHP的集团
Zend引擎V2.2.0,版权所有(C)1998-2009 Zend技术
解决方案
下面是一个函数收拾任意大小的整数值为N个位:
功能连接code_int的($的,$ pad_to_bits = 64,$ LITTLE_ENDIAN = TRUE){
在$ = decbin($的);
在$ = str_pad($中,$ pad_to_bits,'0',STR_PAD_LEFT);
$ OUT ='';
为($ i = 0,len个$ =的strlen($的); $ I< $ len个; $ I + = 8){
$ OUT = CHR(bindec(SUBSTR($中,$ I,8)));
}
如果($ LITTLE_ENDIAN)$ OUT = strrev($出);
返回$输出;
}
下面是一个函数脱$ C C打包的整数$:
函数去code_int的(放; $数据,$位= FALSE){
如果($位===虚假)$位=的strlen($数据)* 8;
如果($位< = 0)返回false;
开关($位){
案例8:
$收益率=解压('C',$数据);
$收益= $收益[1];
打破;
案例16:
$收益率=解压('V',$数据);
$收益= $收益[1];
打破;
案例24:
$收益率=解压('CA / AB / CC',$数据);
$收益= $收益['一'] +($返回['B']<< 8)+($返回['C']<< 16);
打破;
案例32:
$收益率=解压('V',$数据);
$收益= $收益[1];
打破;
案例48:
$收益率=解压('VA / VB / VC,$数据);
$收益= $收益['一'] +($返回['B']<< 16)+($返回['C']<< 32);
打破;
案例64:
$收益率=解压('弗吉尼亚州/ VB',$数据);
$收益= $收益['一'] +($返回['B']<< 32);
打破;
}
返回$返回;
}
Can anyone tell me why I get the following output on x64 architecture:
$ php -r 'echo pow(2, 33) . "\n";print_r(unpack("Ivalue", pack("I", pow(2, 33))));'
8589934592
Array
(
[value] => 0
)
It seems as though it can handle signed 64bit ints, but can't pack / unpack them. According to the docs: http://us3.php.net/pack, the size of I should be machine dependent, which in this case is 64bit.
Thanks.
EDIT Should have mentioned this in the original post:
$ php -r 'echo PHP_INT_MAX;'
9223372036854775807
EDIT 2
$ 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
解决方案
Here is a function to pack an integer value of any size into N bits:
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;
}
Here is a function to decode the packed integers:
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;
}