本课时有配套视频讲解,购买后即可观看(永久有效)
高精度加运算
一、课上练习
编程练习
- 高精度加运算:L3011
二、知识总结
✨ 核心思想
高精度运算是指在计算机科学和数值计算中,能够处理和运算非常大的数字的技术。在编程中,普通的整数类型(如 int 或 long)有其最大值的限制,超过这个范围的运算就会溢出。为了处理更大的数字,比如在大数加密、科学计算或经济模型分析中,就需要用到高精度(大数)运算。
高精度加运算是高精度运算中最基础的一种,其思路与我们手算竖式加法完全一致:从个位开始逐位相加,遇到满十则向高位进一。
✨ 算法原理
高精度加法的实现步骤如下:
- 字符串存储:使用
string类变量来存储整个大数,字符串的每个字符可以直接映射到每一位上的数字。这样可以突破基本数据类型的位数限制。 - 逆序存入数组:将每一位上的数字逆序存储进数组中。逆序存储的目的是让数组下标 0 对应个位,方便从低位开始计算并处理进位。
- 逐位相加并进位:从低位到高位完成对应位相加的操作,在加的过程中进行进位处理。如果某一位的和大于等于 10,则向高一位进 1,当前位保留个位数。
- 逆序输出结果:逆序输出按位加的结果,还原为正常的数字顺序。
✨ 代码实现
以下是高精度加法的完整实现,包括字符串转数组、逐位相加和结果输出三个核心函数:
高精度加运算代码示例
1#include <iostream>
2using namespace std;
3
4// 将字符串s中的数字转换为整数数组a,每位倒序存储
5void convert(int a[], string s) {
6 int len = s.length(); // 获取字符串长度
7 for (int i = 0; i < len; i++) {
8 a[i] = s[len - 1 - i] - '0'; // 将字符串末尾的字符转换为数字,存储在数组的开始处
9 }
10}
11
12// 打印整数数组a表示的数字,数组a中的数字是倒序存储的
13void print(int a[], int len) {
14 for (int i = 0; i < len; i++) {
15 cout << a[len - 1 - i]; // 从后向前打印数组元素,以正确顺序显示数字
16 }
17 cout << endl;
18}
19
20// 实现两个数字的高精度加法,结果存储在result数组中,len为结果的长度
21void addition(int a1[], int len1, int a2[], int len2, int result[], int &len) {
22 for (int i = 0; i < len; i++) {
23 result[i] += a1[i] + a2[i]; // 将对应位相加,并加上之前的进位
24 if (result[i] >= 10) { // 检查是否需要进位
25 result[i + 1]++; // 进位
26 result[i] -= 10; // 当前位保留个位数
27 }
28 }
29 if (result[len] != 0) { // 检查最后的进位,如果有,则结果长度增加1
30 len++;
31 }
32}
33
34int main() {
35 string s1, s2;
36 int a1[105] = {0}; // 存储第一个数的数组,初始化为0
37 int a2[105] = {0}; // 存储第二个数的数组,初始化为0
38 cin >> s1 >> s2; // 读取两个大数
39 int len1 = s1.length(); // 第一个字符串的长度
40 int len2 = s2.length(); // 第二个字符串的长度
41 convert(a1, s1); // 转换第一个字符串为整数数组
42 convert(a2, s2); // 转换第二个字符串为整数数组
43
44 int result[105] = {0}; // 存储结果的数组,初始化为0
45 int len = max(len1, len2); // 计算结果数组的初始长度
46
47 addition(a1, len1, a2, len2, result, len); // 执行加法运算
48
49 print(result, len); // 打印结果
50 return 0;
51}✨ 执行示例
以计算 385 + 97 为例:
第一步:字符串存储
- 输入 s1 = "385",s2 = "97"
第二步:逆序存入数组
- a1[] = {5, 8, 3}(对应个位5、十位8、百位3)
- a2[] = {7, 9}(对应个位7、十位9)
第三步:逐位相加并进位(len = max(3, 2) = 3)
| 步骤 | 位置i | a1[i] | a2[i] | result[i]累加 | 是否进位 | result[i]最终 | result[i+1]进位 |
|---|---|---|---|---|---|---|---|
| 1 | 0(个位) | 5 | 7 | 0+5+7=12 | 是 | 2 | +1 |
| 2 | 1(十位) | 8 | 9 | 1+8+9=18 | 是 | 8 | +1 |
| 3 | 2(百位) | 3 | 0 | 1+3+0=4 | 否 | 4 | 0 |
result[] = {2, 8, 4},len = 3
第四步:逆序输出
- 从 result[2] 到 result[0],输出
482
验证:385 + 97 = 482,正确。
✨ 解题步骤详解
当你遇到一道高精度加法题时,可以按以下步骤思考:
- 判断是否需要高精度:看数据范围,如果数字位数超过 18 位(
long long的极限),就需要高精度。 - 读入数据:用
string读入大数。 - 逆序转换:将字符串逆序存入
int数组,注意字符'0'到'9'需要减去'0'转为数字。 - 确定结果长度:初始长度为两个数中较长的那个。
- 逐位相加:从下标 0 开始,对应位相加,满 10 进 1。
- 检查最高位进位:如果最高位有进位,结果长度加 1。
- 逆序输出:从高位到低位输出。
✨ 常见错误
- 数组大小不够:两个 100 位的数相加,结果可能有 101 位,数组至少要开
max位数 + 2。 - 忘记初始化数组为 0:未初始化会导致垃圾值参与运算,结果错误。
- 字符转数字时忘记减
'0':s[i]是字符,值为 ASCII 码(如'3'是 51),必须减去'0'(48)才能得到数字 3。 - 逆序存储的方向搞反:应该让数组下标 0 存个位(字符串的最后一个字符),而不是最高位。
- 进位处理不完整:只在循环内处理进位但忘记检查最高位是否还有进位。
三、课后练习
编程练习
- 大整数加法:L3012