2011-03-28 99 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

相關問題