加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何将四个字符转换成Perl中的32位IEEE-754 float?

发布时间:2020-12-15 22:01:47 所属栏目:大数据 来源:网络整理
导读:我有一个项目,其中一个函数接收四个8位字符,需要将生成的32位IEEE-754浮点数转换为常规Perl数字.似乎应该比下面的工作代码更快的方式,但是我还没有找到一个更简单的包功能. 不行 – 看起来很接近 $float = unpack("f",pack("C4",@array[0..3]); # fails for
我有一个项目,其中一个函数接收四个8位字符,需要将生成的32位IEEE-754浮点数转换为常规Perl数字.似乎应该比下面的工作代码更快的方式,但是我还没有找到一个更简单的包功能.

不行 – 看起来很接近

$float = unpack("f",pack("C4",@array[0..3]);  # fails for small numbers

作品

@bits0 = split('',unpack("B8",pack("C",shift)));
@bits1 = split('',shift)));
@bits2 = split('',shift)));
@bits3 = split('',shift)));
push @bits,@bits3,@bits2,@bits1,@bits0;

$mantbit = shift(@bits);
$mantsign = $mantbit ? -1 : 1;
$exp = ord(pack("B8",join("",@bits[0..7])));  
splice(@bits,8);

# convert fractional float to decimal 
for (my $i = 0; $i < 23; $i++) {     
 $f = $bits[$i] * 2 ** (-1 * ($i + 1));
 $mant += $f;
}
$float = $mantsign * (1 + $mant) * (2 ** ($exp - 127));

任何人都有更好的方法吗?

解决方法

我会采取相反的方法:忘记开箱,坚持点点滴滴.

首先,组装你的32位字.取决于字节顺序,这可能必须是相反的方式:

my $word = ($byte0 << 24) + ($byte1 << 16) + ($byte2 << 8) + $byte3;

现在提取单词的部分:符号位,指数和尾数:

my $sign = ($word & 0x80000000) ? -1 : 1;
my $expo = (($word & 0x7F800000) >> 23) - 127;
my $mant = ($word & 0x007FFFFF | 0x00800000);

组合你的浮动:

my $num = $sign * (2 ** $expo) * ( $mant / (1 << 23));

wikipedia有一些例子.

>在0xC2ED4000 =>上测试-118.625它可以工作.>在0x3E200000 =>上测试0.15625发现了一个bug! (固定)>当$expo == 255时,不要忘记处理无限和NaN

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读