高精度
作者:互联网
高精度
题目要求:
a) 涉及知识点:数组、流程控制、函数等
b) 要求:用整型数组表示10进制大整数(超过2^32的整数),数组的每个元素存储大整数的一位数字,实现大整数的加减法。
实现细节:
-
完全模拟简单计算过程:读入数据,储存数据,处理数据,输出数据
存储 读入
这里,根据题目要求,要用整数数组来储存,但是介于整数数组读入困难的问题,应该使用字符串来处理输入,然后再对字符串就行处理输入到整数数组中,读入字符串时,数字最高位在字符串首(下标小的位置)。但是习惯上,下标最小的位置存放的是数字的 最低位,即存储反转的字符串。例下图输入15604121072时,先储存进char数组中,采用字符串读取,然后反转处理成整数存储在整数数组中。
代码实现:
void read(int a[]) { static char s[LEN + 1]; //静态 scanf("%s", s); clear(a); int len = strlen(s); // 反转 for (int i = 0; i < len; ++i) a[len - i - 1] = s[i] - '0'; // 字符转数字 }
输出
从后向前找不为零的数,然后按位依次输出即可
void print(int a[]) { int i; for (i=LEN-1;i>=1;--i) //这里判定不能限定为i>=0;这样的话执行完i=-1,会导致无输出 if (a[i] != 0) break; for (; i>=0;--i) putchar(a[i] + '0'); putchar('\n'); }
加法:
按照竖式加法,从最低位开始,将两个加数对应位置上的数值相加,并判断是否达到或超过10 。如果达到,那么处理进位:将更高一位的结果上增加 1,当前位的结果减少10 。(可以考虑取模,和除法,但是不可能出现大于18的情况,所以没必要)
本题所设定的最大位数为LEN=1000位,但一般令数组的最大长度 LEN 比可能的输入大一些, 然后略去末尾的几次循环,可以省去不少边界情况的处理,故在此循环到 LEN - 1 = 1003 已经足够
代码:
void add(int a[], int b[], int c[]) { clear(c); for (int i = 0; i < LEN - 1; ++i) { c[i]+=a[i]+b[i]; // 将相应位上的数码相加 if (c[i] >= 10) { c[i + 1]+=1; c[i]-=10; } } }
减法:
判定:先判定前面是否大于后面,如果不大于就换位,同时在前面加负号,
首先判断位数,位数大的大,然后相等时从最高位向低位判断,如果对应位后大于前,说明传入的第一个数比第二个数小,直接结束.
int judge(int a[],int b[]){ int i,j,k; //分别最大位 for(i=LEN-1; i>=0;--i) if(a[i]!=0) break; for(j=LEN-1; j>=0; --j) if(b[j] != 0) break; //分别判断 if(i < j) return 0; else if(i>j) return 1; for(; i>= 0;--i){ if(a[i]<b[i]) return 0; } return 1; }
实现:从个位起逐位相减,遇到负的情况则向上一位借 1。
void sub(int a[], int b[], int c[]) { clear(c); for (int i=0; i<LEN-1; ++i) { c[i]+=a[i] - b[i]; // 逐位相减 if (c[i]< 0) { c[i+1]-=1; c[i]+=10; } } }
实现程序:
#include<bits/stdc++.h> static const int LEN = 1004; int a[LEN], b[LEN], c[LEN]; void clear(int a[]) { for (int i=0; i<LEN; ++i) a[i] = 0; } void read(int a[]) { static char s[LEN + 1]; //静态 scanf("%s", s); clear(a); int len = strlen(s); // 反转 for (int i=0; i<len; ++i) a[len - i - 1] = s[i] - '0'; // s[i] - '0' 就是 s[i] 所表示的数值 } void print(int a[]) { int i; for (i=LEN-1;i>=1;--i) //这里判定不能限定为i>=0;这样的话执行完i=-1,会导致无输出 if (a[i] != 0) break; for (; i>=0;--i) putchar(a[i] + '0'); putchar('\n'); } int judge(int a[],int b[]){ int i,j,k; //分别最大位 for(i=LEN-1; i>=0;--i) if(a[i]!=0) break; for(j=LEN-1; j>=0; --j) if(b[j] != 0) break; //分别判断 if(i < j) return 0; else if(i>j) return 1; for(; i>= 0;--i){ if(a[i]<b[i]) return 0; } return 1; } void add(int a[], int b[], int c[]) { clear(c); for (int i = 0; i < LEN - 1; ++i) { c[i]+=a[i]+b[i]; // 将相应位上的数码相加 if (c[i] >= 10) { c[i + 1]+=1; c[i]-=10; } } } void sub(int a[], int b[], int c[]) { clear(c); for (int i=0;i<LEN-1;++i) { c[i]+=a[i]-b[i]; // 逐位相减 if (c[i]<0) { c[i+1]-=1; c[i]+=10; } } } int main() { printf("Please make sure the first num is larger than the second.\nAnd make sure the maximum number of digits is 1000 \n"); read(a); read(b); printf(" the result of add is: "); add(a, b, c); print(c); printf(" the result of sub is: "); if(judge(a,b)) sub(a,b,c); else { putchar('-'); sub(b,a,c);} print(c); return 0; }
d单精度乘法
实现时注意得两个for循环分别判断,要不然前面进位会对结果产生影响导致错误
void mul(int a[],int e){ for(int j=0;j<MAX;j++) b[j] *=e; for(int j=0;j<MAX;j++) if(b[j]>9){ b[j+1]+=b[j]/10; b[j]%=10; } }
标签:10,高精度,int,void,LEN,--,数组 来源: https://www.cnblogs.com/abldy/p/16348498.html