科学网

 找回密码
  注册

tag 标签: 精确计算

相关帖子

版块 作者 回复/查看 最后发表

没有相关内容

相关日志

机器能够实现精确计算吗?
热度 1 accsys 2014-8-18 09:22
机器能够实现精确计算吗? 姜咏江 我们进行超长的数值计算,总是分段进行的。计算机进行超长位数的数值计算,也要分段进行。由于计算机运算器的位数是固定的,因而段的划分总是按着精确运算器的长度进行,即要在数值长度分段不足运算器长度时,要进行补位。 手工计算的数有小数点和正负号,而机器表示的数既无小数点也无符号。因而用机器进行数值计算就要寻找另外的符号和小数点表达方法。因为任何一个数都可以写成一个整数和一个整数次幂相乘的形式。例如 -26.567 = -26567 × 10 -3 = -26567 × 1/10 3 。 计算机很容易用二进制将这些数字表示出来,但无法表示符号和指数形式。其实解决整数幂的形式也很简单,只要将幂指数表示出来,让底数隐含就可以了。关键的问题是如何表示正负符号。二进制数只有 0 和 1 两个数码,许多书中都说最高位的数码是符号,这是一个严重的概念错误,因为符号是不能直接参加数值运算的。例如按照这种理解,符号 1+1 表示两个负数相加,结果符号位是 0 ,变成了正数。如果认为结果是 10 ,位数扩充了,但机器位数是有限的,最高位的进位已经丢掉了。如果下面还有进位,那么就更难判断结果的正负符号了。实际上二进制最高位 0 和 1 只是与机器表示正负数方法的一种巧合而已。 1. 对称制 那么机器计算如何表示正负数呢?以中国的算盘为例,能否一见到算盘珠(见 图 1 )就知道是正数还是负数? 图 1 10 进制算盘 这个算盘共有 11 位,能够表示的最大正整数是 99999999999 。这种固定位数的数就叫限位数。我们能否就用这 11 位表示正负数呢?办法是这样的:将 00000000000 ~ 99999999999 从中间 50000000000 分开,让以它为对称的两个数表面数值较大的表示较小的相反数。于是 50000000001 就代表 -49999999999 , 50000000002 就代表 -49999999998 , …… 。因为 50000000000 是自身对称的,为了避免二义性,就规定它代表 -50000000000 。于是这个算盘能够表达有符号整数的范围是 。这种规定表示正负数的方法不用添加任何符号,被称为对称制。 对称制如果是偶数进制( 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. 总结 用限位数理论和方法可以让机器实现准确的算术运算,而不应认为“机器的位数越长越精确”,那是一种错误的理解。一些书中将二进制数的最高位理解成“正负号”,实际上是将“巧遇”当成“一般”,犯了不求甚解的错误。
个人分类: 计算机科普|4119 次阅读|1 个评论
符号位——真的就这么一直错下去吗?
热度 1 accsys 2013-6-13 06:49
符号位——真的就这么一直错下去吗? 姜咏江 以前,我一直奇怪为什么西方的机器表示有符号数搞出一个“符号位”,而符号位的0或1又是不能参加机器数值计算的!我还一直怀疑是不是因为误传。昨天写书,认真地探讨了一下Quartu II中Verilog HDL假定的数据位数,验证了下面一段有符号加减法器的设计程序,才确认他们的理论确实有问题。 / Quartus II Verilog Template // Signed adder/subtractor module signed_adder_subtractor ( input signed dataa, input signed datab, input add_sub, // if this is 0, add; else subtract input clk, output reg result ); parameter WIDTH = 16; always @ (posedge clk) begin if (!add_sub) result = dataa + datab; else result = dataa - datab; end endmodule 利用Quartus II仿真时发现,运算结果总会给你加上一个符号位,显然这个符号位不是二进制数的一部分。例如,h0007-h0016,仿真给出的结果是h1FFF1,多出一位!按照“求反加一”的求值方法,应该得到h1FFF1的值是 -hE000F = - 131057,谬之千里矣!实际的结果值应是-15,也就是必须先去掉符号位求值。在机器运算的时候,也是这样做的吗? 由此我可以断言:至我之前,西方的数学界尚未认真地研究过机器记数的一般方法。 机器运算中随意在数值前面添加0或1,会造成识别与实际计算之间的大麻烦,特别是电路设计,会造成相当数量的浪费。我应当为我的限位数理论自豪。看来机器精确计算还大有搞头。 电子电路设计的科学家们,难道我们还要这样一直错下去吗? 2013-6-13
个人分类: 机器计算|3768 次阅读|2 个评论
精确浮点运算需要监控的信号
accsys 2010-9-24 07:47
姜咏江 计算机加减法运算器的设计需要给用户留出溢出的监控信号,以便用户能够利用存储器进行位数扩充,然后进行分段处理。计算机浮点数运算源自a2 b 的科学记数法,其中a、b是一定位数的二进制数。浮点数加减法运算需要对阶,如果采用小数(尾数)右移的方式对阶,由于位数的限制,会丢失移位小数的部分有效数字,解决的办法是监测这种丢失有效数字的情况,并及时用标志线的信号报告。 8位阶码的浮点数尾数最大的位移是255,因而需要用一个256位的寄存器来承接移出的部分,监控标志线就是标示这个寄存器是否不是0。如果移出的部分小数不是0,且要保持精确计算,那么就需要扩充尾数的位数,进行分段的加减运算(注意,这种向右的位数扩充并不改变阶码,而加减运算的结果溢出,是向左的位数扩充,需要改变阶码)。 如果尾数加减运算的结果溢出,同样需要扩充尾数的位数,但由于尾数是纯小数表示,因而必须将两个尾数都右移同样的位数,同时阶码要增加位移量。 由于浮点加减运算的过程是先对阶,尾数加减之后才能发现运算溢出的,故求结果的阶码非常简单,只要将原先的大阶码加上移位数,就可以得到运算的结果的阶码。 设计浮点运算器要注意右移尾数要先判断正负,二进制右移时,正数高位添0,而负数高位应该添1。 2010-9-24
个人分类: 教学笔记|3651 次阅读|0 个评论
计算机核心设计中心必然转向中国
accsys 2010-6-23 11:19
姜咏江 自从冯.诺依曼计算机设计思想提出之后,计算机就以突飞猛进的速度发展着。从科研、军事到民用,计算机无所不在。然而就是这计算、计算的呐喊声音的背后,核心计算的理论和方法却存在着巨大的遗憾,拼凑式的计算设计方法替代着严格的数值计算理论和方法,其所带来的恶果或许至今那些西方的计算机设计专家还一无所知呢。 从数学的角度来看,数值计算最不能容忍的是二义性。可在西方传过来的机器数值计算方法中,恰恰存在着这种二义性。他们提出了所谓0的概念,例如,在8位二进制的加减法运算中出现10000000,他们就认为这是一个-0,实际上这个8位二进制数唯一表示的是-128。这种规定不仅数学家不能容忍,更糟糕的是会在精确计算中产生莫名其妙的错误,这种错误会造成复杂系统莫名其妙的瘫痪,也许会让发射的火箭在毫无错误编程的情况下发生爆炸。 按着这种糟糕的认识,那么应该有: 10000000 = 1000000000000000 = 10000000000000000000000000000000 = 它们都是-0,理所当然上面的等式是成立的。可见这种错误是多么的严重!实际,上面3个二进制数的值应是-128,-32768,-2147483648,如何能认为它们是相等的? 这种设计的拼凑方法影响了计算机精确计算的发展,体现在IEEE 754所谓的浮点数标准上更是问题多多。看其规定: 如果 指数 是0 并且 小数部分 是0,这个数是0(和符号位相关); 如果 指数 = 2 e 1 并且 小数部分是0,这个数是 无穷大(同样和符号位相关); 如果 指数 = 2 e 1 并且 小数部分非0,这个数表示为不是一个数(NaN)。 其中e是二进制数的位数。 对于IEEE规定的8位阶码的32位浮点数01111111100000000000000000000001就不是一个数了。岂不荒唐!诚然,按照 IEEE 754 单精度浮点数可以在 -0.83886072 127 ~+0.8388607 2 127 范围内运算,但这种规定会造成数值域的不完备,使其无法进行等值扩充,即使引入双精度浮点数的规范,仍然存在着这个问题。 中国当代不乏有世界著名的数学家,计算机界不乏有精明的头脑,在计算机精确计算领域,只要我们不盲从西方的所有理论和技术,深入研究,借助当代计算机面临重大改革时机,敢于挑战,世界计算机核心设计的中心一定会快速地转移到中国来。 我说的是计算机核心设计中心,而不是计算机制造中心。 2010-6-23
个人分类: 计算机核|3750 次阅读|1 个评论
计算机位数越长越精确吗?
accsys 2010-4-30 05:46
姜咏江 计算机厂商经常以计算机的位长作为卖点,似乎让用户深信:计算机位数越长越精确,性能越好。其实未必如此。 计算机运算的精确度并不是由运算器的位数来决定的,而要看能否与存储器配合起来,设计好相应的指令,才能够精确地进行计算。这里给出用8位教学计算机求255以内自然数阶乘的例子,足可以说明这方面的问题。读者有兴趣还可以做后面的练习。 例 求自然数N! (255!的精确结果长度为210个字节) 我们只求一个不超过255的阶乘问题的解决。由于部分积位数的不断增加,必须用分段相乘的方法处理。 用4位十进制作786542642361,我们可以如下分步操作。 (1)42642361=10067304,然后作 (2)78652361=18569265,还要作 (3)18569265+1006=18570271,最后的结果是 (4)185702717304。 如果被乘数位数再多,那么要不断地进行(2)(3)的操作,将其用一条指令来完成,就设计出了乘加指令MADD。 这里采用由低向高的乘,方便知道部分积的长度。从1k(k=1)开始,将每次与乘数k相乘的一个字节放在pw0中,每次乘得的结果(部分积)放在p开始的位置,高字节在高地址处。 变量分配是在数据存储器当中进行的,从0号单元开始。 2010-4-29
个人分类: 教学笔记|6331 次阅读|3 个评论

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-17 22:51

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部