4

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によると、I のサイズはマシンに依存する必要があり、この場合は 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
4

4 に答える 4

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;
    }
于 2012-07-31T02:04:36.907 に答える
0

pack("I")x86_64 上の I32LP64 モデルの場合、整数を要求します。これは通常、少なくとも C では 32 ビット幅です。インタープリターは、独自の定義を上に追加することがよくあります。

于 2010-12-30T17:28:25.737 に答える
0

pack は 2 番目のパラメーターを文字列として受け取り、それを 32 ビットの int に変換するためです。唯一の救済策は、ビットサイズの制限に関する限り符号なしです。ソースコードを見ると、「Q」を使用して 64 ビット マシン エンディアンを強制する 64 ビット バージョンが Perl から間もなく登場することがわかります。

于 2012-07-03T21:33:38.333 に答える