|||
机器能够实现精确计算吗?
姜咏江
我们进行超长的数值计算,总是分段进行的。计算机进行超长位数的数值计算,也要分段进行。由于计算机运算器的位数是固定的,因而段的划分总是按着精确运算器的长度进行,即要在数值长度分段不足运算器长度时,要进行补位。
手工计算的数有小数点和正负号,而机器表示的数既无小数点也无符号。因而用机器进行数值计算就要寻找另外的符号和小数点表达方法。因为任何一个数都可以写成一个整数和一个整数次幂相乘的形式。例如 -26.567 = -26567×10-3 = -26567×1/103。
计算机很容易用二进制将这些数字表示出来,但无法表示符号和指数形式。其实解决整数幂的形式也很简单,只要将幂指数表示出来,让底数隐含就可以了。关键的问题是如何表示正负符号。二进制数只有0和1两个数码,许多书中都说最高位的数码是符号,这是一个严重的概念错误,因为符号是不能直接参加数值运算的。例如按照这种理解,符号1+1表示两个负数相加,结果符号位是0,变成了正数。如果认为结果是10,位数扩充了,但机器位数是有限的,最高位的进位已经丢掉了。如果下面还有进位,那么就更难判断结果的正负符号了。实际上二进制最高位0和1只是与机器表示正负数方法的一种巧合而已。
1. 对称制那么机器计算如何表示正负数呢?以中国的算盘为例,能否一见到算盘珠(见图1)就知道是正数还是负数?
图1 10进制算盘
这个算盘共有11位,能够表示的最大正整数是99999999999。这种固定位数的数就叫限位数。我们能否就用这11位表示正负数呢?办法是这样的:将00000000000~99999999999从中间50000000000分开,让以它为对称的两个数表面数值较大的表示较小的相反数。于是50000000001就代表-49999999999,50000000002就代表-49999999998,……。因为50000000000是自身对称的,为了避免二义性,就规定它代表-50000000000。于是这个算盘能够表达有符号整数的范围是[-50000000000,49999999999]。这种规定表示正负数的方法不用添加任何符号,被称为对称制。
对称制如果是偶数进制(2、4、6、8、10、……),判断一个数实际是正数还是负数,只要比较最高位是否比对称轴的最高位大小即可。例如,84500000000的最高位8比5大,故它表示的是一个负数。
2. 对称制加减法对称制可以做加减法运算,并且可以用加法运算得到减法运算的结果。我们将用数码表示的限位数直接相加就叫限位数加法。例如03219876321+20998760452,10000000000-88888888888。
限位数的加法03219876321+20998760452=24218636773,结果正确。而10000000000-88888888888=10000000000+11111111112=21111111112,这是因为88888888888实际上是-11111111112,因而才会有上面的等式。可以证明对称制中,“减去一个限位数等于加上它的对称码”,也就是说,在对称制中用加法可以替代减法运算!
3. 怎样快速得到对称码?两个数码之和为最大数码,那么一个数码就叫另一个数码的反码。一个限位数的每一位数码都是另一个限位数的对应位的反码,那么这两个限位数也互称为反码。可以证明:一个限位数的对称码等于其反码加一。
这样我们要得到一个限位数的对称码就十分容易了不是?
4. 对称制位数扩充限位数表示数的位数有限,加法运算可能会超出位数,而使实际的数值不对了,这种情况叫溢出。只要我们扩充位数,溢出就不会发生。在对称制中,保持数值不变,可以证明:负数扩充位数左面添“最大数码”,正数添“0”。例如,567扩充成11位,则有567=99999999567,因为在三位限位数中567是-433,而在11位的99999999567的值也是-433。
5. 分段计算超过机器位数的数可以依据机器的位长,将数按位长分段,高段不足位长的要按照正负数的扩充方法补齐数码,然后将减法变成加法,并分段进位,就可以最后得到准确的结果。
实际上乘除法可以转化成连续的加减法运算,故而用机器的限位数方法可以实现整数的加减乘除运算。如果考虑小数点移位,就可以进行任何用数码表示的实数运算。
6. 总结用限位数理论和方法可以让机器实现准确的算术运算,而不应认为“机器的位数越长越精确”,那是一种错误的理解。一些书中将二进制数的最高位理解成“正负号”,实际上是将“巧遇”当成“一般”,犯了不求甚解的错误。
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-12-21 23:06
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社