我有值在值之间浮动的整数:4000000000-4294967000(小于4字节无符号整数的int max)
我希望将其保存到文件,然后重新读取值
$f = fopen($fileName, 'wb'); fwrite($f, pack('I', $value));
重要的是,在文件中,值必须是精确的4字节无符号整数,因为外部设备会期望数据格式。但PHP将大值存储为float,并销毁二进制表示。
我如何将这些数字写成该格式的文件?
[编辑] @FractalizeR这是我的工作:
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,并且这个二进制文件是否会生成正确的?
答案 0 :(得分:1)
好吧,将4个字节的数字分成2个2字节的数字(整数除以256 * 256得到第一个字,然后从原来的一个字减去该值得到第二个字)并写入两个包。
答案 1 :(得分: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)
);
答案 2 :(得分:1)
不要担心它是漂浮物。如果它在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" }
答案 3 :(得分:-1)
使用bcmath()处理您的号码,并进行保存,请按照FractalizeR的说法进行操作。