浮点数的计算机内部表示
见计算机中的浮点数表示 - 简书 (jianshu.com)和浅尝Pytorch自动混合精度AMP_Dr_David_S的博客-CSDN博客、计算机组成原理:IEEE754标准中,为什么指数真值e变成阶码加上的偏移值是127不是128?_Junieson的博客-CSDN博客_ieee754为什么阶码偏移是127中表示。
十进制小数到二进制浮点数的表示过程:
(1)将浮点数转为二进制表示
(2)将小数点向左或向右移动n为,直到小数点前的整数部分为1,得到移动数(左移便是正数,右移便是负数)
(3)移动位数加上偏移量(32位浮点数偏移量为127,64位则1023),将之转换为2进制后得到exponent部分的值。
(4)将小数点后的数字截取部分(32位浮点数最多截取23位,64位浮点数最多截取52位),不足部分补0,作为fraction存储。
反之,二进制浮点数到十进制小数的过程位:
(1)查看符号位,确定为正数还是负数
(2)查看指数位(阶码位),32位则减去其偏移量127,64位同理(减去偏移量1023)
(3)根据尾数部分(fraction)计算小数部分
(4)添加小数位,增加1.的隐藏位,根据移位长度对小数点进行偏移
(5)利用二进制转为为十进制小数。
下面为写的简单32位2进制的浮点数还原为10进制小数的python代码:
1 class Convertfloat32: 2 def __init__(self, binary_value_str): 3 assert len(binary_value_str) == 32, 'input str must has 32 components' 4 self.binary_value_str = binary_value_str 5 6 # 符号位,指数位,尾数位的划分 7 def _split_float32(self): 8 sign = eval(self.binary_value_str[0]) 9 exponent = self.binary_value_str[1:9] 10 fraction = self.binary_value_str[9:] 11 return sign, exponent, fraction 12 13 def _sign_cal(self, sign): 14 return (-1)**sign 15 16 def _exponent_cal(self, exponent): 17 out = 0 18 for i, v in enumerate(exponent[::-1]): 19 out += eval(v) * (2**i) 20 out -= 127 # 32位浮点数偏移量为127 21 return out 22 23 def _float_cal(self, float_str): 24 left_str, right_str = float_str.split('.') 25 value_int = 0 26 value_float = 0 27 for i, v in enumerate(left_str[::-1]): 28 value_int += eval(v) * (2**i) 29 for i, v in enumerate(right_str): 30 value_float += eval(v) * (2**(-(i+1))) 31 return value_int + value_float 32 33 34 def run(self): 35 sign, exponent, fraction = self._split_float32() 36 sign_ = self._sign_cal(sign) 37 exponent_ = self._exponent_cal(exponent) 38 binary_float_str = '1.' + fraction 39 40 if exponent_ < 0: 41 binary_float_str = binary_float_str.rjust(len(binary_float_str)+abs(exponent_), '0') 42 binary_float_str_list = list(binary_float_str) 43 pop_index = binary_float_str_list.index('.') 44 binary_float_str_list.pop(pop_index) 45 binary_float_str_list.insert(1, '.') 46 binary_float_str = ''.join(binary_float_str_list) 47 float_value = self._float_cal(binary_float_str) 48 print(float_value) 49 50 51 if __name__ == '__main__': 52 53 float_32 = '00111110110011001100110011001101' 54 # fraction_list = '10011001100110011001101' 55 # out = float_cal(fraction_list) 56 # print(out) 57 convert_util = Convertfloat32(float_32) 58 convert_util.run()
因此,可以得到float32(单精度浮点数)和float64(double 双精度浮点数)的最小值和最大值范围: