是否可以使用perl的vec()函数存储浮点数?

时间:2011-03-28 22:35:30

标签: perl vector floating-point

我有一个处理数百万行性能数据的perl脚本,所以我需要一种方法来有效地存储度量信息。我发现了perl的vec()函数,它允许你直接操作字符串的位。这可用于以内存有效的方式模拟数组。

它适用于存储整数值。但对于浮点值,它不能很好地工作。

以下是一个例子:

#!/usr/bin/perl

my ($s) = '';

vec($s, 0, 32) = 1234;
vec($s, 1, 32) = 12.34;
vec($s, 2, 32) = pack('f', 12.34);

print "1st vec: " . vec($s, 0, 32) . " (should be '1234')\n";
print "2nd vec: " . vec($s, 1, 32) . " (should be '12.34')\n";
print "3rd vec: " . unpack ('f', vec($s, 2, 32)) . " (should be '12.34')\n";

在我的机器上运行此代码(Mac OS X 10.6.7,perl 5.8.9)将返回以下内容:

1st vec: 1234 (should be '1234')
2nd vec: 12 (should be '12.34')
3rd vec:  (should be '12.34')

正如您所看到的,在简单的情况下,perl只是将浮点数向下舍入到最接近的整数。我甚至试图通过使用pack() / unpack()来获得幻想,但这只是将所有位都清零。

我尝试了几种变体,增加了比特数,谷歌搜索等等都无济于事。这似乎应该可行,因为在一天结束时,它只是一点点。

感谢。

1 个答案:

答案 0 :(得分:4)

vec只写整数,这就是为什么第二个例子中的12.34被转换为12.第三个例子中的压缩字符串被转换为0,unpack('f',0)失败。 / p>

一种解决方案是将打包值写为整数,

  vec($s, 2, 32) = unpack('L', pack('f', 12.34));
  print unpack('f', pack('L', vec($s, 2, 32))), "\n";


但是,最好不要通过vec使用绕行,而是使用substr的4参数版本,即指定(expr,offset,length,replacement):

 substr($s, 2*4, 4, pack("f", 12.34));
 print unpack("f", substr($s, 2*4)), "\n";