高精度练习之加减乘除
最近突然想起以前刷题遇到了高精度的练习,觉得很有必要总结一下,于是重新将加减乘除写了一遍,高精度因为位数的限制,输入必须用字符数组,中间进行转换,具体的加减乘除直接上代码。
减法:先比较俩个数组的大小,数组大的减小的就不需要操作,小的减大的变为大的减小的,同时在角标为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; } }
加法减法还是比较方便的,乘除法是转换为加减法进行计算的。