1. 程式人生 > >php byte十六進位制與float的轉換

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;