高精度练习之加减乘除

最近突然想起以前刷题遇到了高精度的练习,觉得很有必要总结一下,于是重新将加减乘除写了一遍,高精度因为位数的限制,输入必须用字符数组,中间进行转换,具体的加减乘除直接上代码。

减法:先比较俩个数组的大小,数组大的减小的就不需要操作,小的减大的变为大的减小的,同时在角标为0处赋值为-1;

加法:对应位置的数相加,超过10就向前进一位;

乘法:对于数组b的每一个数进行单独相乘,用temp进行存储,然后将temp加入到sum数组中。

除法:从起始位置进行比较,大于被除数就直接减去被除数,小于被除数就向后移动一位,再进行比较。

#include<iostream>
#include<cstring>
#define MAX 501
using namespace std;
int num1[MAX];
int num2[MAX];
int temp[MAX * 2-1];
int SUM[MAX * 2-1];
char ch1[MAX];
char ch2[MAX];
int getFirst(int a[]);
int min(int a, int b) { return a > b ? b : a; }
void add(int a[], int b[], int c[], int all_num);
int comp(int a[], int b[]);
void sub(int a[], int b[], int c[]);
void sub_d(int a[], int b[], int c[]);
void multip(int a[], int b[], int c[]);
void division(int a[], int b[], int c[]);
int comp2(int a[], int start_a, int b[], int start_b);
int main(){
    cin >> ch1;
    cin >> ch2;

    int ch1_num = 0;
    int ch2_num = 0;
    while (ch1[ch1_num] != '\0') ch1_num++;
    while (ch2[ch2_num] != '\0') ch2_num++;
    for (int i = 0; i < ch1_num; i++){
        num1[500 - i] = ch1[ch1_num - i-1]-'0';
    }
    for (int i = 0; i < ch2_num; i++){
        num2[500 - i] = ch2[ch2_num - i - 1]-'0';
    }

    //-----------sub------------------

    //sub(num1, num2, SUM);
    //if (SUM[0] == -1) cout << "-";
    //for (int i = getFirst(SUM); i <= 500; i++){
    //    cout << SUM[i];
    //}
    //cout << endl;

    //------------add-----------------

    //add(num1, num2, SUM, 500);
    //for (int i = getFirst(SUM); i <= 500; i++){
    //    cout << SUM[i];
    //}

    //-----------multip---------------

    //multip(num1, num2, SUM);
    //for (int i = getFirst(SUM); i <= 1000; i++){
    //    cout << SUM[i];
    //}

    //-----------division-------------

    division(num1, num2, SUM);
    for (int i = getFirst(SUM); i <= 500; i++){
        cout << SUM[i];
    }
    cout << endl;

    return 0;
}
int getFirst(int a[]){
    int i = 1;
    while (a[i] == 0) i++;
    return i;
}
void add(int a[], int b[],int c[],int all_num){
    int num_a = getFirst(a);
    int num_b = getFirst(b);
    int num_min = min(num_a, num_b);
    for (int i = all_num; i >=num_min; i--){
        c[i] += a[i] + b[i];
        int j = i;
        while(c[j] >= 10){
            c[j - 1] += c[j] / 10;
            c[j] = c[j] % 10;
            j--;
        }
    }
}
int comp(int a[], int b[]){
    for (int i = 1; i <= 500; i++){
        if (a[i] > b[i]) return 1;
        if (a[i] < b[i]) return -1;
    }
    return 0;
}
void sub(int a[], int b[], int c[]){
    switch (comp(a,b))
    {
    case 0:
        return;
    case 1:
        sub_d(a, b, c);
        return;
    case -1:
        sub_d(b, a, c);
        c[0] = -1;
        return;
    default:
        break; 
    }
}
void sub_d(int a[], int b[], int c[]){
    int num_a = getFirst(a);
    for (int i = 500; i >= num_a; i--){
        if (a[i] >= b[i]){
            c[i] = a[i] - b[i];
        }
        else{
            c[i] = 10 + a[i]-b[i];
            int j = i-1;
            a[j]--;
            while (a[j] < 0){
                a[j] += 10;
                a[j - 1]--;
                j--;
            }
        }
    }
}
void multip(int a[], int b[], int c[]){
    int num_a = getFirst(a);
    int num_b = getFirst(b);
    int temp[MAX * 2];
    //for (int i = 0; i < MAX * 2; i++){ temp[i] = 0; }
    for (int i = 500; i >= num_b; i--){
        memset(temp, 0, sizeof(temp));
        for (int j = 500; j >= num_a; j--){
            temp[i + j] += b[i] * a[j];
            int k = i + j;
            while (temp[k] > 10){
                temp[k - 1] += temp[k] / 10;
                temp[k] = temp[k] %10;
                k--;
            }
        }
        int num_t = getFirst(temp);
        int num_c = getFirst(c);
        int num_min = min(num_t, num_c);
        for (int i = 1000; i >= num_min; i--){
            c[i] += temp[i];
            int j = i;
            while (c[j] >= 10){
                c[j - 1] += c[j] / 10;
                c[j] = c[j] % 10;
                j--;
            }
        }
    }
}
void division(int a[], int b[], int c[]){
    int num_a = getFirst(a);
    int num_b = getFirst(b);
    int i = num_a;
    int j = num_b;
    while (i <= j){
        if (comp2(a, i, b, j) == 1){
            c[500 - j + i] += 1;
            int k = 500 - j + i;
            for (; k >= i; k--){
                a[k] -= b[k + j - i];
                int tem = k;
                while (a[tem] < 0){
                    a[tem] += 10;
                    a[tem - 1]--;
                    tem--;
                }
            }
        }
        else{
            a[i + 1] += a[i] * 10;
            i++;
        }

    }
}
int comp2(int a[], int start_a, int b[], int start_b){
    if (start_a > start_b) return -1;
    if (start_a == start_b){
        int i = start_a;
        while (i <= 500){
            if (a[i] > b[i]) return 1;
            if (a[i] < b[i]) return 0;
            i++;
        }
        return 1;
    }
    if (start_a < start_b){
        for (int i = start_a, j = start_b; j <= 500;i++,j++){
            if (a[i] > b[j]) return 1;
            if (a[i] < b[j]) return 0;
        }
        return 1;
    }

}

加法减法还是比较方便的,乘除法是转换为加减法进行计算的。

posted @ 2018-02-27 14:19  微风&细雨  阅读(197)  评论(0编辑  收藏  举报