php byte十六进制与float的转换

参考  http://blog.sina.com.cn/s/blog_7f0562030102x04i.html

一个浮点数由2部分组成:底数m 和 指数e。
 ±mantissa × 2exponent

(注意,公式中的mantissa 和 exponent使用二进制表示)浮点数据就是按下表的格式存储在4个字节中:
  Address+0    Address+1    Address+2    Address+3
  Contents:    SEEE EEEE    EMMM MMMM    MMMM MMMM    MMMM MMMM     
       S: 表示浮点数正负,1为负数,0为正数

            E: 指数加上127后的值的二进制数

      M: 24-bit的底数(只存储23-bit,最高位始终为 1)
       主意:这里有个特例,浮点数 为0时,指数和底数都为0,但此前的公式不成立。因为2的0次方为1,所以,0是个特例。
       以上面的数据为例:
      这四个字节在内存中为:

16进制:45 33 83 76

2进制:0100 0101  0011 0011 1000 0011 0111 0110

S为0,表示正数。E为1000 1010,即138,减去127为11。M为1.011 0011 1000 0011 0111 0110,右移11位为1011 0011 1000. 0011 0111 0110。转换为10进制为2872.21630859375。

代码:

$hex_two = base_convert($hex,16,2);
            
            $hex_all = "";
            if(strlen($hex_two)%2==0){
                $hex_all = $hex_two;
            }else{
                $hex_all = "0".$hex_two;
            }

            $count_hex = strlen($hex_all)-1;
            $hex_py = substr($hex_all,1,8);  //第一位是正负,前八位偏移量
            $py_sjz = bindec($hex_py);  //转十进制
            $py = $py_sjz - 127;       //补位
            $zs_py_e = substr($hex_all,9,$py);
            $zs_e = "1".$zs_py_e;   //整数部分二进制
            $zs_s = bindec($zs_e);

            $xs_jj = 9+$py;          //小数部分
            $xs_py_e = substr($hex_all,$xs_jj,$count_hex);
            $xs_s = 0;
            for ($i=1; $i < strlen($xs_py_e); $i++) { 
                $xs_s = $xs_s+$xs_py_e[$i]*pow(2,-$i);
            }

            $xs_s = $xs_s/2;


            $count_xs = strlen($xs_s)-1;
            $xs_s = substr($xs_s,2,$count_xs);
          

            $return = $zs_s.".".$xs_s;
            $return_value = round($return,6);
            return $return_value;

猜你喜欢

转载自blog.csdn.net/qq_34815528/article/details/81711264