背景
定点整数只能表示二进制整数,如 −11,而定点小数只能表示仅包含小数部分的二进制纯小数,如 −0.1。但更多时候,数值是既包含整数部分又包含小数部分的二进制混合数,如 −11.1。要表示混合数,需要使用浮点数。
在本关中,假设阶码和尾数都用 8 位补码表示,则对于一个二进制混合数 x,如果 x=0,则其规格化浮点数是全 0,否则按如下方法计算:
至此,彻底解决了计算机如何用 0 和 1 表示二进制数中 +、− 和 . 的问题。
任务
本关任务是实现ZhenToFu(z)函数,其功能是将给定的真实值z转换成规格化浮点数,说明如下:
1)参数z是字符串,表示的是一个二进制数;
2)z对应的真实值的符号可能是+或-,也可能没有,如没有,表示是正数,如’+11.1’、’-11.1’、‘11.1’都是z可能的取值;
3)z对应的真实值的可能是整数(没有小数点)、纯小数和混合数,如’111’、‘0.111’、'11.1’都是z可能的取值;
4)函数的返回值是用字符串表示的规格化浮点数,阶码和尾数都采用 8 位补码形式,阶码和尾数之间有一个空格;
5)若涉及将十进制数转换成二进制的操作,可以使用 Python 提供的bin函数(详见“数值信息——除二取余”实训最后一关)。
相关知识
提示:myCoding库是专门为本实训编写的一个库,你可以根据需要使用库中函数:
ZhenToDing_int(z):将真实值z转换为原码形式的 8 位定点整数(即第 1 关任务),如z为’+10’时,返回值为’00000010’;
ZhenToDing_point(z):将真实值z转换为原码形式的 8 位定点小数(即第 4 关任务),如z为’-0.111’时,返回值为’11110000’;
YuanToBu(y):将 8 位原码y转换成 8 位补码(即第 3 关部分任务),如y为’11110000’时,返回值为’10010000’。
此外,本关主要有两个难点:
1)真实值的格式不固定,可能包含正负号和小数点,也可能不包含,可以在开始时统一处理,若无正号和小数点,则添加,从而可以统一处理。
2)如何计算真实值z对应的阶码和尾数?尾数的主要组成部分其实就是首个 1 到最后一个 1 之间的部分(但要去除小数点,并在前面添加正负号和’0.’),而阶码可以根据首个 1 的位置和小数点的位置计算得到(纯小数和非纯小数计算方法稍有区别)。此外,你可以将这部分功能封装成一个函数。
编程要求
在 Begin-End 区间实现ZhenToFu(z)函数,具体要求见上。
测试说明
例如,测试集 1 的输入为:
-11.1
测试集 1 的输出为:
-11.1 -> 00000010 10010000
开始你的任务吧,祝你成功!
import myCoding
N = 8 #位数为8
########## Begin ##########
def jiema(z):
# 判断正负
if '-' in z:
f = '-'
z = z[1:]
elif '+' in z:
f = '+'
z = z[1:]
else:
f = '+'
zl = [i for i in z]
if '.' not in zl:
zl.append('.')
# 计算小数点的位置
j = zl.index('.')
# 纯小数和非纯小数
if eval(z) < 1: # 纯小数
# 判断满足z >= 0.1,不满足右移一位,直到成立
c = 0
while eval(z) < 0.1:
zl.pop(j)
j = j + 1
zl.insert(j, '.')
c = c + 1
z = ''.join(zl)
# 计算小数点右移了多少位 c
# c转换成二进制定点整数并为负数(真实值)
e = '-'+bin(c)[2:]
# 小数点右移后的数字就是尾数M,加上符号
m = f + '0.' + z.split('.')[1]
else: # 非纯小数
# 判断是否满足z <= 0.1,否则一直左移,直到成立
# 计算小数点右移了多少位 x
# x转换成二进制定点整数并为正
# 小数点左移后的数字就是尾数M,加上符号
c = 0
while eval(z) > 0.1 and j!=0:
zl.pop(j)
j = j - 1
zl.insert(j, '.')
c = c + 1
z = ''.join(zl)
e = '+' + bin(c)[2:]
m = f + '0' + z
return e,m
def ZhenToFu(z):
if eval(z) == 0:
return N*'0'+' '+N*'0'
# 取整数与小数部分真值
d,x = jiema(z)
# 整数部分转原码 + 补码
dbu = myCoding.YuanToBu(myCoding.ZhenToDing_int(d))
# 小数部分转原码 + 补码
xbu = myCoding.YuanToBu(myCoding.ZhenToDing_point(x))
# 拼接整数补码 + 空格 + 小数补码
f = dbu + ' '+xbu
return f
########## End ##########
z = input() #真实值
f = ZhenToFu(z) #转换成浮点数
print('%s -> %s' % (z, f))