代码之家  ›  专栏  ›  技术社区  ›  canni

以无符号二进制形式写入大的4字节整数

  •  5
  • canni  · 技术社区  · 14 年前

    我有一个在值之间浮动的整数:4000000000-4294967000(对于一个4字节的无符号int,它小于int max)

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

    在文件中,值必须是精确的4字节无符号int,这一点很重要,因为外部设备需要这种格式的数据。但是PHP将这些大值存储为float,并破坏二进制表示。

    [编辑]

    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 回复  |  直到 14 年前
        1
  •  1
  •   Vladislav Rastrusny    14 年前

    好吧,把这个4字节的数字分成2个2字节的数字(整数除以256*256得到第一个字,然后从原来的字中减去这个值得到第二个字),然后写进两个包。

        2
  •  1
  •   Artefacto    14 年前

    别担心它是浮子。如果在2^31和2^32-1之间,就不会有任何问题。

    PHP float有52位尾数,因此可以存储32位数字而不丢失精度。

    pack 要对整数进行编码并向其传递一个浮点,它将浮点转换为整数。值为2^31和2^32-1之间整数的浮点,在32位计算机上转换为负数:

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

    在64位计算机上,也会得到一个整数:

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

    但它们的字节表示完全相同。 包装

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

    如果你想分钱 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

        4
  •  -1
  •   Community CDub    8 年前

    使用bcmath()计算数字,如FractalizeR所述保存。

    Arithmetic with Arbitrarily Large Integers in PHP