写大4字节整数为一个无符号二进制

问题描述:

我有一个整数,其值之间浮动:4000000000-4294967000(小于INT最多为4字节无符号整数)写大4字节整数为一个无符号二进制

,我想将它保存到文件,然后再读取值

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

,在文件中,值必须是精确的4字节无符号整型,因为外部设备将期望数据的格式是很重要的。但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个字节数为2个2字节数(由256 * 256整数除法以获得所述第一单词和减去从原始一个值,以获得第二个)并写入两个包。

+0

嘿,thx :)你可以检查我的执行工作是否正确吗? – canni 2010-08-31 10:14:48

使用bcmath()来处理您的数字,并保存,如FractalizeR所说。

一般而言,见Arithmetic with Arbitrarily Large Integers in PHP

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

+0

这不是PHP :) – 2010-08-31 18:55:51

不要担心它是一个浮动。如果介于2^31和2^32-1之间,则不会有任何问题。

PHP浮点数有一个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) 

但是它们的字节表示是完全一样的。 pack将返回相同的两个:

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