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;