• C++知识点 高精度


    一.高精度加法

    1.1 高精度加法

            高精度运算的基本运算就是加和减。和算数的加减规则一样,模拟竖式计算,考虑错位运算与进位处理。

    #include <cstdio>
    #include <cstring>
    int main()
    {
    char a[202]={0}, b[202]={0};
    scanf("%s%s", a, b);
    int alen = strlen(a), blen = strlen(b), t = 0, i;
    int a1[202]={0}, b1[202]={0};
    for (i = 0; i < alen; i++)    a1[i] = a[alen-1-i]-'0';
    for (i = 0; i < blen; i++)    b1[i] = b[blen-1-i]-'0';
    alen = (alen > blen) ? alen : blen;
    for (i = 0; i <= alen; i++)
    t = a1[i]+b1[i], a1[i] = t%10, a1[i+1] += t/10;
    while (!a1[i] && i) i--;
    for(; i >= 0; i--) printf("%d", a1[i]);
    return 0;
    }

    1.2 高精度加法(压位)(清北学堂成果)

          int型可以存9位数字,而上述代码在数组的每个元素中只存了0-9中的一位数,可以说浪费了很多空间,而且计算机计算4+5和3333+4444用的时间是相同的,所以我们有时候用压位来节省空间和时间。其原理如下:

          从键盘读入大整数并存放在字符数组中

          从后向前每八位数字存放在一个int型数组的一个元素中

          对两个数组的对应元素进行加减运算,有进位要进位,最后输出

    #include <iostream>
    #include <cstring>
    #include <cstdio> 
    using namespace std;
    const int INF = 1E8;
    struct Data{
    int u[50], l;
    Data(){
    memset(u, 0, sizeof(u)), l = 0;
    }
    void change(string a){
    int len = a.size(), k = len / 8, i = 0;
    l = k + (len%8 > 0);
    for (len; len > 8; len -= 8)
    sscanf(a.substr(len-8, 8).c_str(), "%d", &u[i++]);
    if (len > 0) sscanf(a.substr(0, len).c_str(), "%d", &u[i]);
    }
    void print(){
    int k = l-1;
    printf("%d", u[k--]);
    while (k >= 0) printf("%8.8d", u[k--]);
    printf("
    ");
    }
    }a, b;
    int main(){
    string aa, bb, ac;
    cin >> aa >> bb;
    int ka = 0, kb = 0, i;
    a.change(aa), b.change(bb);
    for (i = 0; i < 50; i++)
    a.u[i] += b.u[i], a.u[i+1] += a.u[i] / INF, a.u[i] %= INF;
    for (i = 49; a.u[i]==0 && i>0; i--);
    a.l = i + 1;
    a.print();
    return 0;
    }

    二.高精度减法
    2.1 高精度减法

          原理和加法一样,需要不过考虑的不是进位,而是借位。

          代码如下:

    #include <cstdio>
    #include <cstring>
    int main()
    {
    char a[202]={0}, b[202]={0};
    scanf("%s%s", a, b);
    int alen = strlen(a), blen = strlen(b), t = 0, i;
    int a1[202]={0}, b1[202]={0};
    for (i = 0; i < alen; i++)    a1[i] = a[alen-1-i]-'0';
    for (i = 0; i < blen; i++)    b1[i] = b[blen-1-i]-'0';
    alen = (alen > blen) ? alen : blen;
    for (i = 0; i <= alen; i++)
    t = a1[i]-b1[i], t<0?(t+=10,a1[i+1]--):t, a1[i] = t;
    while (!a1[i] && i) i--;
    for(; i >= 0; i--) printf("%d", a1[i]);
    return 0;
    }

    2.2 高精度减法(压位)(同样是清北成果)

          减法和加法大同小异,如果你会了加法,那么减法也不足为惧。

    #include <iostream>
    #include <cstring>
    #include <cstdio> 
    using namespace std;
    const int INF = 1E8;
    struct Data{
    int u[50], l;
    Data(){
    memset(u, 0, sizeof(u)), l = 0;
    }
    void change(string a){
    int len = a.size(), k = len / 8, i = 0;
    l = k + (len%8 > 0);
    for (len; len > 8; len -= 8)
    sscanf(a.substr(len-8, 8).c_str(), "%d", &u[i++]);
    if (len > 0) sscanf(a.substr(0, len).c_str(), "%d", &u[i]);
    }
    void print(){
    int k = l-1;
    printf("%d", u[k--]);
    while (k >= 0) printf("%8.8d", u[k--]);
    printf("
    ");
    }
    }a, b;
    int main(){
    string aa, bb, ac;
    cin >> aa >> bb;
    int ka = 0, kb = 0, i,t;
    a.change(aa), b.change(bb);
    for (i = 0; i < 50; i++)
    t = a.u[i] - b.u[i],(t < 0)?(t+=INF,a.u[i+1]--):t,a.u[i] = t; 
    for (i = 49; a.u[i]==0 && i>0; i--);
    a.l = i + 1;
    a.print();
    return 0;
    }

    这些代码的前提条件是a>=b,所以前面需要有个判断,判断错误还需要把a,b翻转

    三.高精度乘法

        基本原理如下

                            3    2    1    0                    ——>数组a、b的下标

                            3    4    5    6       i            ——>数组a[]

                        *  1    2    7    8       j            ——>数组b[]

                   ————————————

                     2    7    6    4    8 

                2    4    1    9    2

                6    9    1    2

          3    4    5    6

    ——————————————————

          4    4    1    6    7    6    8                ——>数组c[]

          6    5    4    3    2    1    0        i+j    ——>数组c的下标

    以上是俩个四位数相乘的竖式计算方法。可以看出,数的右面对齐,从低位向高位计算,计算结束后将一列结果相加即为答案。那么把俩个数从右向左依次标记为0、1、2...n,那么每一列的结果就是第一个数的下标为i的数与第二个数的下标为j的数相乘的结果,其存放在第i+j列。最终结果是每一列相加,就是i+j这一列所有数相加。所以可以用c[i+j] += a[i]*b[j]。

    for(int i = 0;i < LA;i++)
    for(int j = 0;j < LB;j++)
    c[i+j] += a[i]*b[j];
    for(int i = 0;i < LA+LB;i++)
    if(c[i] >= 10)
    {
    c[i+1] += c[i]/10;
    c[i] %= 10; 
    }


    背过代码一时爽,多背几段会更爽(--QAQ--)

  • 相关阅读:
    js把日期字符串转换成时间戳
    JS array 数组
    for循环中的if嵌套
    第三章:图像增强
    直方图均衡化
    第二章:数字图像处理基础
    马赫带效应
    图片格式
    4邻接,8邻接和m邻接
    第一章:绪论
  • 原文地址:https://www.cnblogs.com/Jiangxingchen/p/12469373.html
Copyright © 2020-2023  润新知