任务描述
背景
第 1 关提到,二进制中除了 0 和 1,还有 +、− 和 .,而计算机底层只有 0 和 1。之前关卡解决的是如何用 0 和 1 表示正负号的问题,从本关开始要进一步解决小数点的问题。
问题的难点在于不能直接用 0 和 1 表示小数点这个符号。例如,若用 1 表示小数点,则二进制数 101.01 对应的表示为 101101,计算机无法区分哪个 1 是小数点,用 0 或其它 01 串表示都存在类似问题。
解决方法是固定小数点的位置。例如,可以做如下规定,在 8 位原码中,小数点位置总是在第 4 位和第 5 位之间,固定不变,则 01010100 表示的数是 +101.0100,即 101.01,从而不用再直接表示小数点了,因为它的位置是已知的。这种表示方式叫定点数。
在实际使用时,一般将小数点位置固定在以下两个位置:
1)数字部分之后,如 8 位原码 00000001 表示的是 +0000001.,即 +1,这种方式叫定点整数,之前关卡介绍的其实都是定点整数;
2)符号位之后、数字部分之前,如 8 位原码 00000001 表示的是 +.0000001,即 +0.0000001,这种方式叫定点小数,定点小数可以表示纯小数。
你可能会问,那 00000001 表示的到底是 +1 还是 +0.0000001,计算机如何区分它是定点整数还是定点小数?其实计算机无法区分,需要提前告诉计算机,这个数采用的是哪种表示方式,计算机才能正确处理。
定点整数在之前关卡已经介绍,本关主要涉及定点小数。将一个纯小数转换成定点小数过程与第 1 关类似:转换符号位、填入数字部分、补 0,但补 0 位置是在数字部分最后。例如,−0.101 转换为 8 位定点小数,过程如下:
定点小数也存在原码、反码、补码形式,如上图给出的是原码形式的计算过程,而根据原码求补码方法与之前相同,如 −0.101 对应的 8 位定点小数的补码形式是 10110000。
如果你不太熟悉该过程,可以参照上面的例题尝试以下计算:
任务
本关任务是实现ZhenToDing_point(z)函数,其功能是将给定的真实值z转换成原码形式的 8 位定点小数,说明如下:
1)参数z是字符串,表示的是一个二进制纯小数;
2)z对应的真实值的符号可能是+或-,也可能没有,如没有,表示是正数,如’-0.101’、’+0.101’、'0.101’都是z可能的取值;
3)函数的返回值是字符串类型,表示真实值z对应的原码形式 8 位定点小数。
相关知识
注:初始代码中的myCoding是专门为本实训编写的一个库,里面包含的YuanToBu(y)函数可以将一个 8 位原码y转换成补码形式。在本关,你编写的代码不需要使用这个库。
编程要求
在 Begin-End 区间实现ZhenToDing_point(z)函数,具体要求见上。
测试说明
例如,测试集 1 的输入为(真实值):
-0.101
测试集 1 的输出为(真实值->原码形式定点小数->补码形式定点小数):
-0.101 -> 11010000 -> 10110000
开始你的任务吧,祝你成功!
import myCoding
N = 8 #位数为8
########## Begin ##########
def ZhenToDing_point(z):
zl = [i for i in z]
if zl[0] == '-':
zl[0] = '1'
zl.pop(1)
elif zl[0] == '+':
zl[0] = '0'
zl.pop(1)
else: # 无符号正数
pass
zl.pop(zl.index('.'))
for i in range(N-len(zl)):
zl.append('0')
return ''.join(zl)
########## End ##########
z = input() #真实值
y = ZhenToDing_point(z) #求定点小数(原码形式)
b = myCoding.YuanToBu(y)#求定点小数(补码形式)
print('%s -> %s -> %s' % (z, y, b))