将程序视点设为星标精品文章第一时间阅读
大家好,欢迎来到程序视点
!我是小二哥。
在上一篇文章中,我们解释了计算机的底层只能处理小数的基础逻辑。今天我们继续。
前情回顾
回顾下,定点数的含义。约定计算机中小数点的位置,且这个位置固定不变,小数点前、后的数字,分别用二进制表示,然后组合起来就可以把这个数字在计算机中存储起来,这种表示方式叫做「定点」
表示法,用这种方法表示的数字叫做「定点数」
。
也就是说「定」是指固定的意思,「点」是指小数点,小数点位置固定即定点数名字的由来。
定点数表示方法
前面,我们说过,任何一个数,我们都可以看成这样格式:
整数部分
小数部分
那必然就有这三种情况:
纯整数
例如整数100,小数点其实在最后一位,所以忽略不写
如果我们以 1 个字节(8 bit)表示,用定点数表示如下(D为十进制缩写,B为二进制缩写):
代码语言:javascript复制100(D) = 01100100(B)
这种情况用定点数表示都比较简单,按照十进制转为二进制规则,即可得到结果。
纯小数
例如:0.125,小数点固定在最高位
同样以 1 个字节(8 bit)表示,用定点数表示如下:
代码语言:javascript复制0.125(D) = 0.00100000(B)
// 这里的小数点是虚拟的。主要为了方便大家看
这种情况用定点数表示都比较简单,按照十进制转为二进制规则,即可得到结果。ps:不清楚纯小数转换为二进制的小伙伴,可以查询这篇文章
整数 小数
这种情况下,我们需要先约定小数点的位置。因为是定点数表示法嘛,那就是要固定小数点的位数。
假如以 1 个字节(8 bit)为例,那我们可以约定前 5 位表示整数部分,后 3 位表示小数部分。对于数字 1.5 用定点数表示时,先处理整数1
,那5 bit表示是这样的:
1(D) = 00001
接着是小数上的0.5
,用3 bit表示是这样的:
0.5(D) = 0.100(B)
再把两个部分合起来,结果是这样:
代码语言:javascript复制1.5(D) = 00001 100(B)
这里总结一下用定点数表示一个小数的过程:
- 在有限的 bit 宽度下,先约定小数点的位置
- 整数部分和小数部分,分别转换为二进制表示
- 两部分二进制组合起来,即是结果
又如数字 25.125
用定点数表示就是这样:
25.125(D) = 11001 001(B)
范围和精度问题
刚才我们约定了前 5 位表示整数部分,后 3 位表示小数部分。此时,这个整数部分的二进制最大值只能是 11111,即十进制的 31;小数部分的二进制最大只能表示 0.111,即十进制的 0.875。显然,用后 3 位 bit 位表示小数部分,是不能把小数涵盖完的。
如果我们想要表示更大范围的值,怎么办?
1.扩大 bit 的宽度:例如使用 2 个字节、4 个字节,这样整数部分和小数部分宽度增加,表示范围也就变大了。
2.改变小数点的位置:小数点向后移动,整个数字范围就会扩大,但是小数部分的精度就会越来越低,没有办法表示类似 0.00001 这种高精度的值。
但不管如何约定小数点的位置,我们都会发现这种表示方式存在以下问题:
数值的表示范围有限(小数点越靠左,整个数值范围越小) 数值的精度范围有限(小数点越靠右,数值精度越低)
总的来说,定点数表示小数就是范围有限,精度低。要想解决这 2 个问题,计算机科学家们提出了使用「浮点数」
的方式表示数字。关于「浮点数」
,我们下期接着讲。