其他分享
首页 > 其他分享> > 高精度知识总结

高精度知识总结

作者:互联网

 概念

高精度算法,属于处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿、几千几万位的大数字。这类数字我们无法用基本类型进行存储,这就是高精度。高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。对于非常庞大的数字无法在计算机中正常存储,于是,将这个数字拆开,拆成一位一位的,或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字,这样这个数字就被称为是高精度数。高精度算法就是能处理高精度数各种运算的算法,但又因其特殊性,故从普通数的算法中分离,自成一家。

存储

高精度数,拆成一位一位存储。有很多位,也就是要用很多个变量,那么我们可以用一维数组存储每一位。我们可以从高位到低位存储,也可以从低位到高位存储,但不管哪一种方式,一般数组的第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