5


1

大きな4バイト整数を符号なしのバイナリとして書き込みます

値間を浮動する整数があります:4000000000-4294967000(4バイトの符号なし整数の場合、int maxより小さい)

そして、私はそれをファイルに保存してから値を再読み込みしたい

$f = fopen($fileName, 'wb'); fwrite($f, pack('I', $value));

ファイルでは、値は正確な4バイトの符号なしintである必要があります。これは、外部デバイスがその形式のデータを予期するためです。 しかし、PHPはその大きな値をfloatとして保存し、バイナリ表現を破壊します。

その形式でファイルにその番号を書き込むにはどうすればよいですか?

  • [編集] * @FractalizeR thxこれは私が持っている作品:

protected static function handleUint($direction, $value)
{
    if($direction == 'encode')
    {
        $first2bytes    = intval($value / (256 * 256));
        $second2bytes   = intval($value - $first2bytes);

        return pack('n2', $first2bytes, $second2bytes);
    }
    else
    {
        $arr = unpack('n2ints', $value);
        $value = $arr['ints1'] * (256 * 256) + intval($arr['ints2']) - 1;
        return $value;
    }
}

しかし、私はまったく理解していない、なぜ返り値で-1する必要があり、このバイナリは正しく生成されるのですか?

4 Answer


1


さて、その4バイトの数値を2つの2バイトの数値に分割し(整数を256 * 256で除算して最初の単語を取得し、元の単語からその値を減算して2番目の単語を取得します)、2つのパックに書き込みます。


1


`int`を4バイトに分割したい場合、次のことができます:

int x = 13434;
byte[] buff = new byte[] {
       (byte)((x >> 24) & 0xff),
       (byte)((x >> 16) & 0xff),
       (byte)((x >> 8) & 0xff),
       (byte((x) & 0xff)
}

ここで使用される方法は、ビット単位操作と呼ばれます。

参照:http://en.wikipedia.org/wiki/Bitwise_operation

これが助けになれば幸いです。

編集:

私はこれがあなたがPHPで同じことをする方法だと思う:

$arr = array(
       ((x >> 24) & 0xff),
       ((x >> 16) & 0xff),
       ((x >> 8) & 0xff),
       (x & 0xff)
);

参照:http://php.net/manual/en/language.operators.bitwise.php


1


フロートであることを心配しないでください。 2 ^ 31から2 ^ 32-1の間であれば、問題はありません。

PHPの浮動小数点数には、52ビットの仮数があるため、32ビットの数値を正確に損失することなく格納できます。

`pack`に整数をエンコードするように指示し、それにfloatを渡すと、floatが整数に変換されます。 値が2 ^ 31〜2 ^ 32-1の整数である浮動小数点数は、32ビットマシンでは負の数値に変換されます。

$ php -r "var_dump((int) 4000000000);"
int(-294967296)

64ビットマシンでは、整数も取得します。

$ php -r "var_dump((int) 4000000000);"
int(4000000000)

しかし、それらのバイト表現はまったく同じです。 `pack`は両方で同じを返します:

$ php -r "var_dump(unpack('H*', pack('I', (float) 4000000000)));"
array(1) {
  [1]=>
  string(8) "00286bee"
}


-1


bcmath()を使用して数値を処理し、保存するために、FractalizeRが言ったようにします。

一般的に、https://stackoverflow.com/questions/37391/arithmetic-with-arbitrarily-large-integers-in-php [PHPの任意の大きな整数を使用した算術演算]を参照してください。