16进制字符串转换为32位单精度浮点数

flyingfish

日前,想用gatewayworker接收设备发过来的信息,但是发现php中没有直接将16进制字符串转换为32位单精度浮点数的函数,在网上查了许久,查到了这个 http://www.zhanglirong.cn/article/index/cid/1/id/69.html
[code]$a = '4145C28F';
$v = hexdec($a);
$x = ($v & ((1 << 23) - 1)) + (1 << 23)  ($v >> 31 | 1);
$exp = ($v >> 23 & 0xFF) - 127;
$res = $x 
 pow(2, $exp - 23);
if(($v >> 31) == 1){
    $res = -$res;
}
echo $res;[/code]
对这部分代码的理解的前提是需要了解ieee 754标准中浮点数表示法:http://c.biancheng.net/view/314.html
$v = hexdec($a) ;将字符串$a放到一个32bit的二进制串里:‭01000001010001011100001010001111‬
$x = ($v & ((1 << 23) - 1)) + (1 << 23) ($v >> 31 | 1);取出尾数,并在最左边添加1。
$exp = ($v >> 23 & 0xFF) - 127; 获取阶码。
$res = $x
pow(2, $exp - 23); 根据阶码移动小数点的位置,我觉得这里理解起来比较费劲,我的理解是$x可以理解为一个整数,pow(2,$exp-23)为该整数需要缩小的倍数。比如对于十进制数1000.00来说,缩小两倍,那么小数点就往左移两位。
后面用于判断符号的代码可用a?b:c三目运算符更简洁。
 

3889 5 0
5个评论

keytehu

好文章,虽然有点高深

  • 暂无评论
walkor

感谢你的分享,
试试这个方法
var_export(unpack('G', hex2bin('4145C28F')));
更简单,精度更高

  • 暂无评论
yujingtao

大神:G是什么东西,手册里没有,运行了一下报错

  • 暂无评论
yujingtao

找到了,是单精度浮点型我的手册不是最新的

  • 暂无评论
flyingfish

本来我是想找你给出的这个现成的办法的,查看了unpack和pack函数的参数和用法,然后试了一下,结果得不到正确的结果。看来对这个unpack和pack函数吃的不够深呀。

  • 暂无评论
年代过于久远,无法发表评论

flyingfish

26
积分
0
获赞数
0
粉丝数
2019-07-24 加入
🔝