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

标签 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 只是将 float 向下舍入为最接近的整数。我什至尝试通过使用 pack()/unpack() 来获得乐趣,但这只会将所有位清零。

我已经尝试了更多变体,增加位数,谷歌搜索等都无济于事。这看起来确实应该有效,因为归根结底,一切都只是比特。

谢谢。

最佳答案

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、偏移量、长度、替换):

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

关于perl - 是否可以使用 perl 的 vec() 函数存储 float ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5465839/

相关文章:

c++ - 使用结构的二维 vector

c++ - 对象内部的对象和维护对象的一个​​实例时出现问题

assembly - 是否可以在 NASM 中定义浮点常量 (`equ` )?

c - 为什么 float 数据类型以不同方式对待 X/Y(例如 5/9)和 X.0/Y.0(例如 5.0/9.0)?

java - 如何检查 double 的小数部分是否包含特定数字?

perl - 在 Perl 中,加载模块的 use 和 require 之间有什么区别?

c++ - reinterpret_cast 如何展平 std::vector?

java - 带有前后(。*)慢的Java正则表达式

perl - 如何在 Perl 的单独文件中定义常量?

perl - 如果(且仅当)测试用例成功时,在 Perl 测试中执行检查