Python IEEE754 单精度浮点数二进制十六进制转换

发布时间 2023-09-25 17:24:59作者: 温泉镇谢步东

在学计组的知识,单精度浮点数与二进制十六进制的转换过程,写了几个函数,方便自己检验

  1 hdict = {
  2     '0': '0000',
  3     '1': '0001',
  4     '2': '0010',
  5     '3': '0011',
  6     '4': '0100',
  7     '5': '0101',
  8     '6': '0110',
  9     '7': '0111',
 10     '8': '1000',
 11     '9': '1001',
 12     'A': '1010',
 13     'B': '1011',
 14     'C': '1100',
 15     'D': '1101',
 16     'E': '1110',
 17     'F': '1111',
 18 }
 19 rehdict = {hdict[k]: k for k in hdict}
 20 
 21 
 22 def strh2strb(s: str):
 23     """
 24     16进制字符串转2进制字符串
 25     """
 26     s = s.upper()
 27     rst = []
 28     for o in s:
 29         rst.append(hdict[o])
 30     return ''.join(rst)
 31 
 32 
 33 def strb2int(strb):
 34     """
 35     二进制字符串转int
 36     """
 37     base = 1
 38     rst = 0
 39     for o in strb[::-1]:
 40         if o == '1':
 41             rst += base
 42         base *= 2
 43     return rst
 44 
 45 
 46 def int2strb(n):
 47     """
 48     int 转二进制字符串
 49     """
 50     if n == 0:
 51         return '0'
 52     rst = []
 53     while n > 0:
 54         a = n % 2
 55         rst.append(str(a))
 56         n //= 2
 57     return ''.join(rst[::-1])
 58 
 59 
 60 def frac2strb(n):
 61     """
 62     小数部分转二进制字符串
 63     """
 64     rst = []
 65     while n != 0:
 66         n *= 2
 67         if n < 1:
 68             rst.append('0')
 69         else:
 70             rst.append('1')
 71             n -= 1
 72     return ''.join(rst)
 73 
 74 
 75 def strh2float(s):
 76     """
 77     IEEE754 十六进制字符串转浮点数
 78     """
 79     s1 = strh2strb(s)
 80     #
 81     sign = 1 if s1[0] == '0' else -1
 82     #
 83     es = s1[1:9]
 84     e = strb2int(es) - 127
 85     en = pow(2, e)
 86     #
 87     frac_str = s1[9:]
 88     frac = 1
 89     base = 0.5
 90     for o in frac_str:
 91         if o == '1':
 92             frac += base
 93         base *= 0.5
 94     #
 95     return sign * en * frac
 96 
 97 
 98 def pre0(s):
 99     """
100     计算前导0的个数
101     """
102     ans = 0
103     for o in s:
104         if o == '0':
105             ans += 1
106         else:
107             return ans
108 
109 
110 def float2strb(n):
111     """
112     浮点数转二进制字符串
113     """
114     if n == 0:
115         return '00111111100000000000000000000000'
116 
117     sign = '0' if n >= 0 else '1'
118     #
119     n = abs(n)
120     n1 = int(n)
121     n1s = int2strb(n1)
122     n2 = n - n1
123     n2s = frac2strb(n2)
124     #
125     if n1s == '0':
126         x = pre0(n2s)
127         en = - x - 1
128         e = 127 + en
129         es = int2strb(e)
130         if len(es) < 8:
131             es = '0' * (8 - len(es)) + es
132         #
133         fracs = n2s[x + 1:]
134         strb = sign + es + fracs + '0' * (23 - len(fracs))
135     else:
136         en = len(n1s) - 1
137         e = 127 + en
138         es = int2strb(e)
139         if len(es) < 8:
140             es = '0' * (8 - len(es)) + es
141         #
142         fracs = n1s[1:] + n2s
143         strb = sign + es + fracs + '0' * (23 - len(fracs))
144     return strb
145 
146 
147 def float2strh(n):
148     """
149     浮点数转 IEEE754 十六进制
150     """
151     strb = float2strb(n)
152     rst = []
153     for i in range(0, 32, 4):
154         o = strb[i:i + 4]
155         rst.append(rehdict[o])
156     return ''.join(rst) + "H"
157 
158 
159 if __name__ == '__main__':
160     print(strh2float('41A50000'), 20.625)
161     print(strh2float('C1A50000'), -20.625)
162     print(strh2float('40940000'), 4.625)
163     print(strh2float('C0940000'), -4.625)
164     print(strh2float('3FD00000'), 1.625)
165     #
166     print(float2strh(4.625), '40940000')
167     print(float2strh(-4.625), 'C0940000')
168     print(float2strh(-20.625), 'C1A50000')
169     print(float2strh(20.625), '41A50000')
170     #
171     print(float2strh(1.625), '3FD00000')
172     print(float2strh(0), '3F800000')
173     print(float2strh(-9 / 16), 'BF100000')