2011-03-28 109 views
3

我有一个可以处理数百万行性能数据的Perl脚本,所以我需要一种有效存储度量信息的方法。我发现了perl的vec()函数,它允许你直接操纵字符串的位。这可以用来以一种高效的内存模式来模拟一个数组。使用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()来获得幻想,但是这只是将所有的比特全部清零。

我试了几个变化,增加了位数,谷歌搜索等无济于事。这似乎应该起作用,因为在这一天结束时,这只是一点点。

谢谢。

回答

4

vec只写整数,这就是为什么第二个示例中的12.34被转换为12.第三个示例中的打包字符串被转换为0,并且unpack('f',0)失败。

一种解决方案是编写包装值为整数,

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"; 
+0

谢谢,这正是我一直在寻找的。 – 2011-03-29 00:02:13

相关问题