场景引入
在C++中不同类型的变量都有不同的存储范围
例如:
| 类型 |
字节 |
范围 |
| char |
1 |
|
| int |
4 |
|
| long long |
8 |
|
其中我们可以看到 long long 的存储范围已经相当大了,但是在数位上最多只有19位
这时便产生了一个问题:如何存储大于19位的数呢?
此时就需要使用 高精度算法 来解决问题
原理
高精度算法的原理其实类似于小学数学中学到的竖式计算
举个栗子:

首先计算两个数的个位数 9+2 = 11,保留个位的 1,满 10 进 1
其次计算十位, 9 + 1 = 10,保留个位的 0,满 10 进 1
最后计算百位,保留 1
所以得数就是 101
高精度算法便是通过代码将这一过程进行模拟
代码实现
创建变量
- 创建两个字符串用于输入加数
- 创建三个数组分别用于储存加数和得数
- 创建循环变量
注:数组的大小一定要足够大,例如加数是200位,那么数组大小可以是210
1 2 3
| string s1, s2; int a1[110], a2[110], a3[110] = { 0 }; int i,len;
|
储存加数
- 将加数输入字符串(这里用到的是getline函数)
- 使用两个for循环将字符串倒序储存在数组
注:
- (此例中)数组的下标是从后往前移动,字符串的下标是从前往后移动
- 字符串储存的是字符,所以在储存到数组时要减字符0才能得到对应的数字
1 2 3 4 5 6 7 8 9 10 11
| getline(cin, s1); getline(cin, s2); for (i = 0; i < s1.size(); i++) { a1[s1.size()-i - 1] = s1[i] - '0'; } for (i = 0; i < s2.size(); i++) { a2[s2.size()-i - 1] = s2[i] - '0'; }
|
模拟竖式计算
- 循环的次数取决于两者间最大的数位,此例中用max函数得到最大值赋值给len
- 第一个循环,两个加数对应的数位相加
- 第二个循环,模拟10进制的进位
注:模拟进位时,进1和保留个位两个步骤顺序不能写反
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| len = max(s1.size(), s2.size()); for (i = 0; i < len; i++) { a3[i] = a1[i] + a2[i]; } for (i = 0; i < len; i++) { if (a3[i] >= 10) { a3[i + 1] = a3[i + 1] + a3[i] / 10; a3[i] %= 10; } }
|
调整循环变量
这一步非常重要,得数的位数不一定与加数的最大位数相同
如上文的例子中,得数是3位数,但是两个加数最大是2位数
所以需要进行一步判定
a3已经进行了初始化,所以没有被更改的元素都是0
利用这一点我们可以在下标len处判断此元素是否为0,如果不为0,说明最高位有进位,此时len++
1 2 3 4
| if (a3[len] != 0) { len++; }
|
输出结果
因为加数是逆序储存的,所以在输出时需要再一次逆序,得到正确的结果
1 2 3 4
| for (i = len-1; i >= 0; i--) { cout << a3[i]; }
|
完整代码
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
| #include <iostream> #include <string> using namespace std; int main() { string s1, s2; int a1[110], a2[110], a3[110] = { 0 }; int i; int len; getline(cin, s1); getline(cin, s2); for (i = 0; i < s1.size(); i++) { a1[s1.size()-i - 1] = s1[i] - '0'; } for (i = 0; i < s2.size(); i++) { a2[s2.size()-i - 1] = s2[i] - '0'; } len = max(s1.size(), s2.size()); for (i = 0; i < len; i++) { a3[i] = a1[i] + a2[i]; } for (i = 0; i < len; i++) { if (a3[i] >= 10) { a3[i + 1] = a3[i + 1] + a3[i] / 10; a3[i] %= 10; } } if (a3[len] != 0) { len++; } for (i = len-1; i >= 0; i--) { cout << a3[i]; } return 0; }
|
如果文章内容有误,欢迎指出