- 注册时间
- 2007-12-28
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 12787
- 在线时间
- 小时
|
发表于 2016-4-19 16:54:11
|
显示全部楼层
楼上的算法仍然不够好,仍可改进。
1.将被除数和除数同时乘以\( 10^k \)是不必要的。
2.乘以\( 10^k \)这种方法,可增加被除数和除数的比特数,但是仍不够彻底。
更好的方法。
1. 考察被除数,若被除数最高的m个单元小于除数,最高位补零。
2. 考察除数的最高2个单元,b[0]和b[1], 若\( [b0] \times R + b[1] \) 小于半机器或者1个机器字, 那么做如下预处理。
2.1. 将b[0]和b[1]合并,做 \( b[1] = b[0] \times R + b[1] \),同时将b[0]清0.
2.2. 对被除数也做同样的处理。
这样,将 n个单元的被除数 除以 m个单元的除数 的 除法 转化为 n-1个单元的被除数 除以 m-1个单元除数 的 除法.这个变换仅需做一次。
3.考察除数的最高单元b[0],若其比特数小于半个机器字或者1个机器字,扩大\( 2^k \)倍,将其变半个机器字或者1个机器字,存入 \( bh \),这个步骤也仅需做一次。
4.试商,并依次得到各个部分商,在这个过程中,被除数要扩大同样的倍数,这个过程要重复许多次。
下面以\( R=10^4 \)为例,详细解释下。
例1.被除数为(5,9999,1234,5678),除数为(6,2345,5432)。
step0,预处理:除数的前两个单元表示的数6*R+2345=62345小于半个机器字65536, 将被除数和除数的前2个单元合并。合并后
被除数变为(59999,1234,5678),除数为(62345,5432)
step 1: 除数最高单元为62345,包含16比特数据,无需将其扩大。
step 2.试商,用被除数前2个单元除以除数的第一个单元。
得部分商 \( 9623=(59999 \times 10000+1234) \div 62345 \)
step 3.部分商9623乘以除数(62345,5432),得到部分积(59995,1162,2136)
step 4,被除数减去部分积,得余数(40072,3542)
接着,可重复step2,step3,step4,以得到更多的部分商
注:从这个例子中可以看出,在计算过程中,被除数,部分积和余数的最高位是可以大于R的
例2.被除数为(599,9912,3456),除数为(623,4555)。
step 0,除数的前2个单元表示的数 \( 6234555 > 2^{16} \),不需要做预处理。
step 1. b[0]=623,只有10比特,\( 2^9 < 623 < 2^{10} \) ,乘以\( 2^6 \) 扩大至16比特. 即 \( bh= 623 \times 64 + (4555 \times 64 \div 10000)=39901 \)
step 2. 试商,用被除数前2个单元扩大64位,然后除以除数的第一个单元,得部分商9623
\( 9623=(599 \times 10000+9912)\times 64 \div 39901 \)
step 3.部分商9623乘以除数(623,4555),得到部分积(599,9512,2765)
step 4,被除数减去部分积,得余数(400,0691)
重复 step2,step3,step4得到更多的部分商
这个估商法的优缺点。
1.相对于普通的估商法,这个方法得到的商更加准确,部分商偏小的概率大大降低。
2.相对于楼上的估商法,这个方法不需要将被除数和整数整个乘以 \( 10^k \)
2.相对于普通估商法,在估商时,需要做一个额外的运算步骤,被除数要扩大\( 2^k \)倍,不过,这个操作可用左移指令来实现,增加的成本可忽略不计。
一点儿说明,在实践中,为了避免估商偏大,\( bh \)要稍微取得大一点儿。在例2中。 计算\( bh \)时,其步骤改为 \( bh= (623 \times 64 + 4555 \times 64 \div 10000)+1=39902 \)
|
|