C++ 大数运算

辅导孩子C++编程,实现大数的加法、减法和乘法,思路比较直接,就是模拟手工运算,逐位运算,如果有进位则上一位加一。先程序实现的减法,程序的结构大部分是从减法部分拷贝过来的。为了简化处理,输入认为是长度小于100的数字,没有进行合法性判断。也没有输入输出说明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//大数的加法 
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
char First[100],Second[100];
cin>>First>>Second;

int FirstLen=strlen(First),SecondLen=strlen(Second);

//将输入的数据放到整数数组中,便于计算,结果保存在数组c中
int intFirst[100],intSecond[100],c[100];
//首先初始化,避免非正常结果
for(int i=0;i<100;i++){
intFirst[i]=0;
intSecond[i]=0;
c[i]=0;
}

//输入的顺序是高位在后,低位在前,因此需要颠倒一下
//这里的关键是颠倒后数组下标之间的对应关系
for(int i=FirstLen-1;i>=0;i--){
intFirst[FirstLen-1-i]=First[i]-48;
}

for(int i=SecondLen-1;i>=0;i--){
intSecond[SecondLen-1-i]=Second[i]-48;
}

int len=FirstLen;
if(SecondLen>FirstLen)
len=SecondLen;


//这里可以进行加法法运算了,问题转换为intFirst与intSecond之间的运算
for(int i=0;i<len+1;i++)
{
c[i]=intFirst[i]+intSecond[i]; //按位进行运算
if(c[i]>=10)
{
//如果结果小于0,那么从上一位借1当10,结果需要加上10,上一位减去1
c[i]=c[i]-10;
intFirst[i+1]=intFirst[i+1]+1;
}
}

//下面的代码是输出
bool isZero=true;
for(int i=FirstLen;i>=0;i--)
{
//如果高位是0,就不输出 ,需要注意,如果结果是0 ,应该输出
if(c[i]==0&&isZero&&i>0)
{
continue;
}
cout<<c[i];
isZero=false;
}
}

大数减法的实现的思路也很直接,就是模拟减法运算,将参见运算的数字逐位保存到数组中,然后逐位进行减法运算,如果结果小于0就向高位借一当十。大数运算,加减乘的思路都是一致的,相对比较容易,除法有一定的难度。下面是实现的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
char First[100],Second[100];
cin>>First>>Second;

int FirstLen=strlen(First),SecondLen=strlen(Second);

//将输入的数据放到整数数组中,便于计算,结果保存在数组c中
int intFirst[100],intSecond[100],c[100];
//首先初始化,避免非正常结果
for(int i=0;i<100;i++){
intFirst[i]=0;
intSecond[i]=0;
c[i]=0;
}

//输入的顺序是高位在后,低位在前,因此需要颠倒一下
//这里的关键是颠倒后数组下标之间的对应关系
for(int i=FirstLen-1;i>=0;i--){
intFirst[FirstLen-1-i]=First[i]-48;
}

for(int i=SecondLen-1;i>=0;i--){
intSecond[SecondLen-1-i]=Second[i]-48;
}



//这里可以进行减法运算了,问题转换为intFirst与intSecond之间的运算
for(int i=0;i<FirstLen;i++)
{
c[i]=intFirst[i]-intSecond[i]; //按位进行运算
if(c[i]<0)
{
//如果结果小于0,那么从上一位借1当10,结果需要加上10,上一位减去1
c[i]=c[i]+10;
intFirst[i+1]=intFirst[i+1]-1;
}

}

//下面的代码是输出
bool isZero=true;
for(int i=FirstLen-1;i>=0;i--)
{
//如果高位是0,就不输出 ,需要注意,如果结果是0 ,应该输出
if(c[i]==0&&isZero&&i>0)
{
continue;
}
cout<<c[i];
isZero=false;
}
}

代码中真正的计算部分的代码很少,大部分代码是在处理输入和输出。这部分代码没有很好的优化,直来直去。

大数的乘法比加法减法稍微复杂一些,但思路一样,仍然是模拟手工运算。乘法需要按位相乘,这需要一个中间数组保存每一位相乘的结果,然后将数组中的数按位相加。这里保存输出的结果的数组要大一些。还有就是在最后的加和时,需要错位相加。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//大数的乘法 
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
char First[100],Second[100];
cin>>First>>Second;

int FirstLen=strlen(First),SecondLen=strlen(Second);

//将输入的数据放到整数数组中,便于计算,结果保存在数组c中,中间变量temp,用于存储中间结果
int intFirst[100],intSecond[100],temp[100][200],c[200];
//首先初始化,避免非正常结果
for(int i=0;i<100;i++)
{
intFirst[i]=0;
intSecond[i]=0;

for(int j=0;j<100;j++)
{
temp[i][j]=0;
}
}
for(int i=0;i<200;i++)
{
c[i]=0;
}

//输入的顺序是高位在后,低位在前,因此需要颠倒一下
//这里的关键是颠倒后数组下标之间的对应关系
for(int i=FirstLen-1;i>=0;i--){
intFirst[FirstLen-1-i]=First[i]-48;
}

for(int i=SecondLen-1;i>=0;i--){
intSecond[SecondLen-1-i]=Second[i]-48;
}

//逐位乘
for(int i=0;i<FirstLen;i++)
{
for(int j=0;j<SecondLen;j++)
{
temp[i][j]=intFirst[i]*intSecond[j]+temp[i][j];
if(temp[i][j]>10)
{

temp[i][j+1]=temp[i][j]/10;
temp[i][j]=temp[i][j]%10;
}

}
}

//所有数组逐位相加 ,保存到c中
for(int i=0;i<FirstLen;i++)
{
for(int j=0;j<SecondLen+1;j++)
{
int k=i+j;
c[k]=c[k]+temp[i][j];
if(c[k]>10)
{
c[k]=c[k]-10;
c[k+1]=c[k+1]+1;
}
}
}


//下面的代码是输出
bool isZero=true;
for(int i=199;i>=0;i--)
{
//如果高位是0,就不输出 ,需要注意,如果结果是0 ,应该输出
if(c[i]==0&&isZero&&i>0)
{
continue;
}
cout<<c[i];
isZero=false;
}

return 0;


}