大数运算(整数的加法和乘法)
2018-02-01 16:48
274 查看
大家刚开学的时候肯定都做过A+B吧?今天给大家出一道A+Bplus版:给定两个整数A和B,计算A
+ B的和。(A和B的范围都是0~1e1000) 这道题我们还能用int或者longlong来做吗?
这时候,由于A和B的取值范围远远大于数据类型给定的范围,不能满足较大规模的高精度数值计算,因此需要利用其他方法来实现高精度数值的计算,于是产生了大数运算。大数运算主要有加、减、乘这三种方法(当然大家也可以试着扩展一下其它(比如除法,取模,阶乘等等)
对于本题(大数加法):
1 我们要用多大的数组存储结果?
2 如何在计算的过程中保证进位?
1 ,由于两个数最大为1e1000,所以和的最大位数是2*1e1000,也就是长度为1000的数组。
2 , 在大数加减中执行完毕后再对存储结果的result数组进行一次进位(因为每位中两个十以内的数相加最多只进一位,结果累
积不会造成数据范围溢出)
例如:
8 1 3 5 7 3 8 7 2 5 8 9 7 1 + 3 2 9 4 8 1 3 0 9 1 8 9 0 4 9 5 0 1 8 = 3 29 4 8 9 4 3 (14) 8(11)(17)7 6(14)(13) 9 8 9
最后进位,得:
3 2 9 4 8 9 4 4 4 9 2 7 7 7 5 3 9 8 9
对于大数乘法:
1 我们要用多大的数组存储结果?
2 如何在计算的过程中保证进位?
1,如果两个数最大为1e1000,所以乘积的最大位数是1e(1000+1000),也就是长度为2000的数组。
2, 在大数乘法中可以定义一个中间过程的二维数组,执行完毕后对每一列进行求和,得到结果,最后再对存储结果的result数 组进行一次进位
例如:
8
3 9
7
5
* 9 3 8
= (64) (24) (72) (56) (40)
(24) 9 (27) (21) (15)
(72) (27) (81) (63) (45)
也就是:
7 8 7 6 8 5 5 0
我们来看一下代码的实现:
//大数加法和乘法(整数运算)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAX 1000
using namespace std;
char a[MAX],b[MAX],c[MAX],result[MAX];
int bignum_add(char* a,char* b,char* result)
{
memset(c,0,sizeof(c));
int len_a=strlen(a);
int len_b=strlen(b);
int flag=0,k=0;//进位标志
int i=len_a-1;
int j=len_b-1;
while(i>=0&&j>=0)
{
c[k]+=(a[i]+b[j]-2*'0'+flag)%10;
flag=(a[i]+b[j]-2*'0'+flag)/10;//进位
i--;
j--;
k++;
}
c[k]+=flag;
while(i>=0)
{
c[k++]+=a[i]-'0';
i--;
}
while(j>=0)
{
c[k++]+=b[j]-'0';
j--;
}
for(int i=0;i<k;i++)
result[i]=c[k-i-1]+'0';
result[k]=0;
return k;
}
int bignum_mutil(char* a,char* b,char* result)
{
memset(c,0,sizeof(c));
int len_a=strlen(a);
int len_b=strlen(b);
int flag,k;//进位标志
for(int j=len_b-1;j>=0;j--)
{
k=len_b-1-j;
flag=0;
for(int i=len_a-1;i>=0;i--)
{
c[k]+=(b[j]-'0')*(a[i]-'0')+flag;
flag=c[k]/10;//进位
c[k]=c[k]%10;
k++;
}
if(flag)
c[k++]+=flag;
}
for(int i=0;i<k;i++)
result[i]=c[k-i-1]+'0';
result[k]=0;
return k;
}
int main()
{
while(cin>>a>>b)
{
// memset(c,0,sizeof(c));
char c[MAX]={0};
//大数加法
bignum_add(a,b,c);
int len=strlen(c);
int i;
for(i=0;c[i]=='0';i++);//避免高位为0
if(i>=len)
cout<<0;
else
{
for(i=i;i<len;i++)
cout<<c[i];
}
cout<<endl;
//大数乘法
bignum_mutil(a,b,c);
4000
len=strlen(c);
for(i=0;c[i]=='0';i++);//避免高位为0
if(i>=len)
cout<<0;
else
{
for(i=i;i<len;i++)
cout<<c[i];
}
cout<<endl;
}
return 0;
}
+ B的和。(A和B的范围都是0~1e1000) 这道题我们还能用int或者longlong来做吗?
这时候,由于A和B的取值范围远远大于数据类型给定的范围,不能满足较大规模的高精度数值计算,因此需要利用其他方法来实现高精度数值的计算,于是产生了大数运算。大数运算主要有加、减、乘这三种方法(当然大家也可以试着扩展一下其它(比如除法,取模,阶乘等等)
对于本题(大数加法):
1 我们要用多大的数组存储结果?
2 如何在计算的过程中保证进位?
1 ,由于两个数最大为1e1000,所以和的最大位数是2*1e1000,也就是长度为1000的数组。
2 , 在大数加减中执行完毕后再对存储结果的result数组进行一次进位(因为每位中两个十以内的数相加最多只进一位,结果累
积不会造成数据范围溢出)
例如:
8 1 3 5 7 3 8 7 2 5 8 9 7 1 + 3 2 9 4 8 1 3 0 9 1 8 9 0 4 9 5 0 1 8 = 3 29 4 8 9 4 3 (14) 8(11)(17)7 6(14)(13) 9 8 9
最后进位,得:
3 2 9 4 8 9 4 4 4 9 2 7 7 7 5 3 9 8 9
对于大数乘法:
1 我们要用多大的数组存储结果?
2 如何在计算的过程中保证进位?
1,如果两个数最大为1e1000,所以乘积的最大位数是1e(1000+1000),也就是长度为2000的数组。
2, 在大数乘法中可以定义一个中间过程的二维数组,执行完毕后对每一列进行求和,得到结果,最后再对存储结果的result数 组进行一次进位
例如:
8
3 9
7
5
* 9 3 8
= (64) (24) (72) (56) (40)
(24) 9 (27) (21) (15)
(72) (27) (81) (63) (45)
也就是:
7 8 7 6 8 5 5 0
我们来看一下代码的实现:
//大数加法和乘法(整数运算)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAX 1000
using namespace std;
char a[MAX],b[MAX],c[MAX],result[MAX];
int bignum_add(char* a,char* b,char* result)
{
memset(c,0,sizeof(c));
int len_a=strlen(a);
int len_b=strlen(b);
int flag=0,k=0;//进位标志
int i=len_a-1;
int j=len_b-1;
while(i>=0&&j>=0)
{
c[k]+=(a[i]+b[j]-2*'0'+flag)%10;
flag=(a[i]+b[j]-2*'0'+flag)/10;//进位
i--;
j--;
k++;
}
c[k]+=flag;
while(i>=0)
{
c[k++]+=a[i]-'0';
i--;
}
while(j>=0)
{
c[k++]+=b[j]-'0';
j--;
}
for(int i=0;i<k;i++)
result[i]=c[k-i-1]+'0';
result[k]=0;
return k;
}
int bignum_mutil(char* a,char* b,char* result)
{
memset(c,0,sizeof(c));
int len_a=strlen(a);
int len_b=strlen(b);
int flag,k;//进位标志
for(int j=len_b-1;j>=0;j--)
{
k=len_b-1-j;
flag=0;
for(int i=len_a-1;i>=0;i--)
{
c[k]+=(b[j]-'0')*(a[i]-'0')+flag;
flag=c[k]/10;//进位
c[k]=c[k]%10;
k++;
}
if(flag)
c[k++]+=flag;
}
for(int i=0;i<k;i++)
result[i]=c[k-i-1]+'0';
result[k]=0;
return k;
}
int main()
{
while(cin>>a>>b)
{
// memset(c,0,sizeof(c));
char c[MAX]={0};
//大数加法
bignum_add(a,b,c);
int len=strlen(c);
int i;
for(i=0;c[i]=='0';i++);//避免高位为0
if(i>=len)
cout<<0;
else
{
for(i=i;i<len;i++)
cout<<c[i];
}
cout<<endl;
//大数乘法
bignum_mutil(a,b,c);
4000
len=strlen(c);
for(i=0;c[i]=='0';i++);//避免高位为0
if(i>=len)
cout<<0;
else
{
for(i=i;i<len;i++)
cout<<c[i];
}
cout<<endl;
}
return 0;
}
相关文章推荐
- 大整数加法和乘法STL
- 非负大整数乘法和加法
- 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
- 大数运算(大数加法and大数乘法)
- 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
- 整数高精度运算的库(加法,减法,乘法,除法,取模)
- 双链表实现大整数的加法与乘法[VC++]
- 大精度整数三种运算(加法,减法,乘法)
- 大型整数运算:加法, 减法, 乘法
- 华为机试:无线OSS-高精度整数加法、矩阵乘法计算量估算
- 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
- 判断两个有符号整数的加法和乘法是否溢出
- 用加法实现两个整数乘法操作
- 大整数问题,乘法,加法,阶乘
- 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
- 实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。 例如:输入t
- Java模拟两个大整数的加法、乘法、除法
- [转]双链表实现大整数的加法与乘法[VC++]
- 大整数的乘法与加法
- 任意长度的高精度大整数和浮点数的加法和乘法