关于高精度
作者:焦祺 08-11-8
所谓的高精度运算,是指参与运算的数(加数,减数,因子……)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算。
高精度的特征使我们在运用上一般会借助函数模板,不过在有的情况是需要我们更改的,所以高精度的计算还是值得我们深入研究。
高精度计算的一般分类:
l 高精度加法
l 高精度减法
l 高精度乘法(阶乘)
l 高精度除法(求余)
l 高精度数比较
高精度加法计算原理:
观察人工计算的方法:竖式加法
223
+ 996
-----------
9 3+6=9
1 2+9=11,当前位1,进位1
2 2+9+1=12,当前位2,进位1
1 进位的1
-----------
1219
算法框架:
A为AN位数,B为BN位数,结果存到C
N=AN>=BN?AN:BN;//求得两数的高位
for(从个位开始 TO 两数最高位N)
{
C的第i位 = A的第i位 + B的第i位
进位位 = C第i位 / 10
当前位的值 = C第i位 %10
}
自编高精度加法函数模板:
加法输出函数:
高精度加法计算的时间效率提高方法:
在运用中,加法的高精计算算是比较简单,用起来也比较那灵活多变一点,在简单的题目中可以用二维数组计算打表。这样不用每次都要去调用高精度加法函数,从而可以提高实战中的时间效率。
如:HDOJ1715 ( 大菲波数 )
以上的方法可以较好的解决时间效率的问题,但在有些运用中,空间效率却成为考点,由于计算高精度常用INT数组,所以优化时就要在数组上下功夫了。
如:HDOJ1250 ( Hat's Fibonacci )
高精度减法计算原理:
竖式减法:
927
- 896
-----------
1 7-6=1
3 12-9=3,借位12
0 (9-1)-8=0
-----------
31
注意:
注意减法的特性:借位
不要忽略连续借位!
借位前被借位是0的情况
注意可能出现负数!
前导零处理
算法框架:
for(从个位开始 TO 两数最高位N)
{
if(a的第i位小于b的第i位)
{//那么需要借位
借位位减1
当前位加10
}
a第i位和b第i位的差存入a;
}
自编高精度减法函数模板:
比较函数:
高精度乘法计算原理:
竖式乘法:
1. 大数乘小数,比如12345*9=?
1 2 3 4 5
* 9
--------------
45 5*9=45
36 4*9=36
27 3*9=27
18 2*9=18
+ 9 1*9=9
--------------
1 1 1 1 0 5
2. 大数乘大数,比如12345*12345=?
12345*12345=12345*5+
12345*4*10+
12345*3*100+
12345*2*1000+
12345*1*10000
问题转化为若干个大数乘小数之和
算法框架
用一个i,j二重循环{{res[i+j]+=b[i]*a[j];}}
//不管三七二十一先把结果算出来
//然后我们再来考虑进位:
for(……)
{
如果:res[i] >= 10
那么:
res[i+1] += res[i]/10; //进位位
res[i] %= 10; //原始位
}
自编高精度乘法函数模板:
乘法输出函数:
高精度除法计算原理:
竖式除法----用多次的减法来实现!
36
12345 √ 452678
37035 12345*3=37035
8232 45267-37035=8232
82328 下一位再次减法
74070 12345*6=74070
8258 82328-74070=8258 余数
高精度除以低精度算法框架
d = 0
for(从除数的最高位 to 除数的个位)
{
d += a的第i位
计算d和除数的商 存入C数组中
计算d和除数的余数 存入d中
处理该位的余数便是下一位的十位
}
自编高精度除以低精度函数模板:
高精度除以高精度算法框架
d=0;//余数
for(从除数的最高位 to 除数的个位)
{
d自乘10 //高精度乘10
被除数的第i位加入d中
while(d大于除数)
{
d和除数的差存在d中
商++;
}
}
高精度除法函数模板:
高精度阶乘函数模板:
语法:int result=factorial(int n);
参数:
n:n 的阶乘
返回值:阶乘结果的位数
注意:
本程序直接输出n!的结果,需要返回结果请保留long a[]
需要 math.h
源程序:
PKU上关于高精度的题目汇集:
1001(高精度乘法) 2413(高精度加法,还有二分查找)
1220, 1405, 1503, 1131, 2305,2325,2389,1604,1047
1504 1517 1519 1547 1552 1563(考虑仔细一点,还要注意精度)
2381 2385 2393 2394 2395 2413(高精度基础) //2418 2419
参考文献:
《程序设计基础第2版》吴文虎 清华大学出版社
《ACM程序设计培训教程》 中国铁道出版社