高精度知识总结
作者:互联网
概念
高精度算法,属于处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿、几千几万位的大数字。这类数字我们无法用基本类型进行存储,这就是高精度。高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。对于非常庞大的数字无法在计算机中正常存储,于是,将这个数字拆开,拆成一位一位的,或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字,这样这个数字就被称为是高精度数。高精度算法就是能处理高精度数各种运算的算法,但又因其特殊性,故从普通数的算法中分离,自成一家。
存储
高精度数,拆成一位一位存储。有很多位,也就是要用很多个变量,那么我们可以用一维数组存储每一位。我们可以从高位到低位存储,也可以从低位到高位存储,但不管哪一种方式,一般数组的第0位都是存储高精度数的位数,这样我们可以比较方便的知道数字从哪一位开始输出,从哪一位输出到哪一位。
大多数情况下,都是从低位到高位存储,即个位存储到数组第1位,这样可以比较方便的对齐两个高精度数的个位,也方便进位处理。
输入
因为没有基本的数字类型可以存储,所以需要以字符串的形式输入。
高精度大都可以从低位到高位存储,相反方向原理一样,这里就以从低位到高位存储为例。
不妨设数字串s长度为n,从零开始存储,那么他们将存储到数组a的第1到第n位:
最低位(个位)是s[n-1],存储到a[1];
十位是s[n-2],存储到a[2];
百位是s[n-3],存储到a[3];
……
最高位是s[0],存储到a[n]。
下标之和等于n,所以s[i]存储到a[n-i]。
数字串长度存储到a[0],即a[0] = n。
a[0] = n = strlen(s);
for(i=0; i<n; i++) a[i] = s[n-i] - 48;
输出
从高位开始输出,最高位是a[0],最低位(个位)是a[1],所以输出a[a[0]]...a[1]。
for(i=a[0]; i>=1; i--) printf("%d", a[i]);
加法
原理
1、个位加个位、十位加十位、百位加百位……
2、逢十进一
因为需要进位,如果最高位放在前面(数组第1位),就有可能影响进位。一般的,在进行高精度加法的时候,我们会把个、十、百、千、万……依次存储到数组的第1、2、3、4、5……位。
实现
两个高精度数a和b相加:
n = max(a[0], b[0]);
jin = 0;
for(i=1; i<=n; i++){
c[i] = a[i] + b[i];//逐位相加
if(c[i] > 9) jin = 1, c[i] -= 10;
else jin = 0;//进位处理
}
if(jin) c[0] = n + 1;
else c[0] = n;//最高位处理
减法
原理
1、个位减个位、十位减十位、百位减百位……
2、减出负数,借位加十
3、输出是去掉前导零
实现
高精度数a减高精度数b:
for(i=1; i<=a[0]; i++){
c[i] = a[i] - b[i];//逐位相减
if(c[i] < 0) c[i] += 10, a[i+1]--;//借位处理
}
while(a[0] > 1 && c[a[0]] == 0) a[0]--;
c[0] = a[0];//前导零处理
注意:必须是绝对值大的数减去绝对值小的数。如果小减大,或者有符号,需要预先判断最终结果的正负号,再转化成大减小。
乘法
原理
321
* 321
----------
321
642
+ 963
----------
103041
从这个乘法竖式可以看出,个位(1)乘个位(1)放在个位(1),个位(1)乘十位(2)放在十位(2),……,十位(2)乘个位(1)放在十位(2),十位(2)乘十位(2)放在百位(3),十位(2)乘百位(3)放在千位(4)……可得出此规律:第i位乘第j位放在第i+j-1位。最后每一位加起来即可。
实现
高精度数a乘以高精度数b:
for(i=1; i<=a[0]; i++){
for(j=1; j<=b[0]; j++){
c[i+j-1] += a[i] * b[j];//任意两位相乘求和
}
}
c[0] = a[0] + b[0] - 1;//目前最高位
for(i=1; i<=c[0]; i++){
c[i+1] += c[i] / 10;
c[i] %= 10;//进位处理
}
while(c[i]){//最高位进位处理
c[i+1] += c[i] / 10;
c[i] %= 10, i++;
}
c[0] = i - 1;//最高位
高精度乘以低精度也可以用这个方法,但其实可以更简单。
除法
高精度除以低精度
00038
-------
321/12345
- 963
-------
2715
- 2568
-------
147
模拟厂字除法竖式,将商从高位到个位依次求出来。高精度数从高位开始存储,方便按顺序计算商的每一位。每次“被除数”的计算,需要用到秦九韶算法。
高精度数a除以低精度数b核心代码如下:
s = 0;
for(i=1; i<=a[0]; i++){
s = s * 10 + a[i];
c[i] = s / b;
s = s % b;
}
最终商是高精度数c,余数是s。
标签:总结,存储,数字,高精度,知识,十位,百位,数组 来源: https://blog.csdn.net/m0_60950850/article/details/122011797