忘记是什么时候老师教的大数加减乘除了,也很久没有碰过c或者c++了,在刷面试题的时候发现很多编程题目一开始都会涉及到大数,所以现在就先整理出来进行再一次梳,简单粗暴,代码奉上。
首先普及一下c的数据类型中的整数类型,基本要了解的如下:
类型 | 存储大小 | 范围 |
---|---|---|
char | 1字节 | -128 到 127 或 0 到 255 |
unsigned char | 1字节 | 0 到 255 |
signed char | 1 字节 | -128 到 127 |
int | 4 字节 | -2,147,483,648 到 2,147,483,647 |
unsigned int | 4 字节 | 0 到 4,294,967,295 |
short | 2 字节 | -32,768 到 32,767 |
unsigned short | 2 字节 | 0 到 65,535 |
long | 4 字节 | -2,147,483,648 到 2,147,483,647 |
unsigned long | 4 字节 | 0 到 4,294,967,295 |
当我们进行整数运算时,计算机只能对范围为-2,147,483,648 到 2,147,483,647且结果也在int范围内的整数进行运算,为了防止数据溢出导致的计算机运算错误,我们使用某种办法代替计算机的运算。
#include
#include
#define MAX 100001
using namespace std;
int subtraction(char a[],char b[],int c[]){
int len1,len2,i,j,k;
k=0;
len1=strlen(a)-1;
len2=strlen(b)-1;
for(i=len1,j=len2;i>=0;i--,j--)
{
if(j>=0)//做减法
{
if(a[i]=0;i--)
if(c[i]!=0)
break;
return i;
}
int main(void)
{
char a[MAX],b[MAX];
int c[MAX];
int len;
while(scanf("%s%s",a,b)!=EOF)
{
len=subtraction(a,b,c);
//清0准备输出
if(len>=0)
for(;len>=0;len--)
printf("%d",c[len]);
else
printf("0");
printf("\n");
}
return 0;
}
测试数据
999999999999999999999999999999999999999999999999 22222222222222222222222222222222
结果
999999999999999977777777777777777777777777777777
#include
#include
#define MAX 100001
using namespace std;
int addition(char a[],char b[],int c[]){
int len1,len2,i,j,k,sign;
sign=0;k=0;
len1=strlen(a)-1;
len2=strlen(b)-1;
for(i=len1,j=len2;i>=0||j>=0;i--,j--)
{
if(j>=0&&i>=0)
{
if(a[i]+b[j]+sign>'0'+'0'+9)
{
c[k]=a[i]+b[j]-'0'-'0'-10+sign;
sign=1;
}
else
{
c[k]=a[i]+b[j]-'0'-'0'+sign;
sign=0;
}
}
else if(i>=0&&j<0)
{
if(a[i]+sign>'9')
{
c[k]=0;
}
else
{
c[k]=a[i]-'0'+sign;
sign=0;
}
}
else
{
if(b[j]>='9'&&sign==1) c[k]=0;
else
{
c[k]=b[j]-'0';
sign=0;
}
}
k++;
}
if(sign==1)
{
c[k]=1;
k++;
}
for(i=k-1;i>=0;i--)
if(c[i]!=0)
break;
return i;
}
int main(void)
{
char a[MAX],b[MAX];
int c[MAX];
int len;
while(scanf("%s%s",a,b)!=EOF)
{
len=addition(a,b,c);
//清0准备输出
if(len>=0)
for(;len>=0;len--)
printf("%d",c[len]);
else
printf("0");
printf("\n");
}
return 0;
}
测试数据
444444444444444444444444444 655555555555555555555555555
结果
1099999999999999999999999999
#include
#include
using namespace std;
typedef string BigInt;
BigInt ClearZero(BigInt x) //清除数前面的0
{
int i;
for (i = 0; i < x.length(); i++)
if (x[i] != '0')
break;
if (i == x.length())
return "0";
else
return x.erase(0, i);
}
BigInt addition(BigInt a, BigInt b)
{
int l1 = a.length();
int l2 = b.length();
while (l1 < l2) //将两个数的长度对齐,在两个数前面补0
{
a = '0' + a;
l1++;
}
while (l1 > l2)
{
b = '0' + b;
l2++;
}
a='0'+a;
b='0'+b;
// cout<= 0; i--)
{
if (( a[i] + b[i] )>( '0' + 9 +'0' ))
{
a[i] -= 10;
a[i-1]++;
}
a[i]=a[i]+b[i] - '0';
// cout << a[i] << endl;
}
return ClearZero(a);
}
BigInt multiplication(BigInt a,BigInt b)
{
BigInt c="0",d;
int i,j;
for(j=b.length()-1 ;j>=0;j--)
{
d=a;
for(i=2;i<=(b[j]-'0');i++)
d=addition(d,a);
if((b[j]-'0')>0)c=addition(c,d);
a=a+'0';
}
return c;
}
int main()
{
BigInt a, b;
while (cin>>a>>b)
{
cout<
测试数据
123456789 123456789
运算结果
15241578750190521
#include
#include
#define MAX 100001
using namespace std;
int SubStract(int *p1, int len1, int *p2, int len2)
{
int i;
if(len1 < len2)
return -1;
if(len1 == len2 )
{ // 判断p1 > p2
for(i = len1-1; i >= 0; i--)
{
if(p1[i] > p2[i]) // 若大,则满足条件,可做减法
break;
else if(p1[i] < p2[i]) // 否则返回-1
return -1;
}
}
for(i = 0; i <= len1-1; i++) // 从低位开始做减法
{
p1[i] -= p2[i]; // 相减
if(p1[i] < 0) // 若是否需要借位
{ // 借位
p1[i] += 10;
p1[i+1]--;
}
}
for(i = len1-1; i >= 0; i--) // 查找结果的最高位
{
if( p1[i] ) //最高位第一个不为0
return (i+1); //得到位数并返回
}
return 0; //两数相等的时候返回0
}
int Division(char num1[], char num2[], int sum[])
{
int k, i, j;
int len1, len2, len=0; //大数位数
int dValue; //两大数相差位数
int nTemp; //Subtract函数返回值
int num_a[MAX] = {0}; //被除数
int num_b[MAX] = {0}; //除数
int num_c[MAX] = {0}; //商
len1 = strlen(num1); //获得大数的位数
len2 = strlen(num2);
//将数字字符转换成整型数,且翻转保存在整型数组中
for( j = 0, i = len1-1; i >= 0; j++, i-- )
num_a[j] = num1[i] - '0';
for( j = 0, i = len2-1; i >= 0; j++, i-- )
num_b[j] = num2[i] - '0';
if( len1 < len2 ) //如果被除数小于除数,直接返回-1,表示结果为0
{
return -1;
}
dValue = len1 - len2; //相差位数
for (i = len1-1; i >= 0; i--) //将除数扩大,使得除数和被除数位数相等
{
if (i >= dValue)
num_b[i] = num_b[i-dValue];
else //低位置0
num_b[i] = 0;
}
len2 = len1;
for(j = 0; j <= dValue; j++ ) //重复调用,同时记录减成功的次数,即为商
{
while((nTemp = SubStract(num_a, len1, num_b+j, len2-j)) >= 0)
{
len1 = nTemp; //结果长度
num_c[dValue-j]++; //每成功减一次,将商的相应位加1
}
}
// 计算商的位数,并将商放在sum字符数组中
for(i = MAX-1; num_c[i] == 0 && i >= 0; i-- ); //跳过高位0,获取商的位数
if(i >= 0)
len = i + 1; // 保存位数
for(j = 0; i >= 0; i--, j++) // 将结果复制到sum数组中
sum[j] = num_c[i];
return len; // 返回商的位数
}
int main(void)
{
char a[MAX],b[MAX];
int c[MAX];
int len;
while(scanf("%s%s",a,b)!=EOF)
{
len=Division(a,b,c);
//清0准备输出
if(len>=0)
for(int i = 0; i < len; i++ )
printf("%d",c[i]);
else
printf("0");
printf("\n");
}
return 0;
}
测试数据
15241578750190521 123456789
运算结果
123456789
到现在为止就要结束啦,希望以后还能坚持一直写下去