- 算法学习
高精度除法(1)
- @ 2025-10-1 10:43:18
1. 概念引入:模拟长除法
高精度除法用于计算一个超大整数 (超过内置类型范围)除以一个普通整数 (在 int 范围内)的商和余数。
其核心原理是完全模拟长除法(竖式除法)的过程:
- 从高位开始: 从被除数 的最高位开始,依次向低位进行运算。
- 累积余数: 在每一步除法中,将上一步的余数乘以 10,再加上当前位的新数字,形成新的被除数。
- 求商与新余数: 用这个新被除数除以 ,得到当前位的商,并计算出新的余数,用于下一位的运算。
2. 实现步骤与代码解析
我们将以您提供的代码为例,分步解析高精度除法的实现。
步骤 A:输入与顺序存储
与加、减、乘法不同,长除法是从高位(左侧)开始计算的,因此我们需要顺序存储大整数 的每一位。
代码解析:
char a[200];
int b;
cin >> a >> b; // 输入大整数 A (字符串) 和除数 b (int)
int lena = strlen(a);
// 将 A 顺序存入 a1,最高位在 a1[1]
for(int i = 0; i < lena; i++)
{
// a[0] 存入 a1[1], a[1] 存入 a1[2], 以此类推
a1[i+1] = a[i] - '0';
}
// 此时 a1[1] 是 A 的最高位,a1[lena] 是 A 的个位。
步骤 B:核心运算——长除法的模拟
这一步是除法的核心。我们使用一个循环从 的最高位开始遍历,并用一个变量 来存储每一步的余数(即进位到下一位的数值)。
关键变量:
x:当前累积的余数 (Remainder),初始化为 0。
循环逻辑:
int x = 0; // x 用来存储上一位运算后的余数
for(int i = 1; i <= lena; i++) // 遍历 A 的每一位(从高位到低位)
{
// 1. 形成新的被除数:上一步余数 * 10 + 当前位数字
int current_dividend = x * 10 + a1[i];
// 2. 求商:新的被除数 / b
c[i] = current_dividend / b;
// 3. 更新余数:新的余数是 current_dividend % b,用于下一位的运算
x = current_dividend % b;
}
- 特点: 在每一步迭代中,数组
c[i]存储的是除法结果的第 位商。变量x在循环结束后,存储的就是最终的余数。
步骤 C:处理前导零与输出结果
商的结果可能会有前导零(例如 )。我们需要跳过这些无效的前导零,然后按顺序输出商的每一位。
代码解析:
int lenc = 1;
// 跳过前导零。当 c[lenc] == 0 且还没有到达个位时,lenc++
// 确保如果结果是 0,至少会输出一个 0
while(c[lenc] == 0 && lenc < lena)
{
lenc++;
}
// 顺序输出商的每一位
for(int i = lenc; i <= lena; i++)
{
cout << c[i];
}
// 最终余数 x 已经被计算出来,但这段代码只输出了商
如何输出余数?
在上述代码的循环结束后,变量 x 中存储的就是最终的余数。如果需要输出余数,可以在 for 循环后添加:cout << endl << x;。
3. 完整代码(高精度除法)
#include <bits/stdc++.h>
using namespace std;
int a1[200], c[200]; // a1 存储被除数,c 存储商
int main()
{
char a[200];
int b; // 除数 b 是 int 类型
cin >> a >> b;
int lena = strlen(a);
// --- 步骤 A: 顺序存储被除数 A ---
for(int i = 0; i < lena; i++)
{
a1[i+1] = a[i] - '0';
}
// --- 步骤 B: 模拟长除法,计算商和余数 ---
int x = 0; // 余数 (Remainder)
for(int i = 1; i <= lena; i++)
{
// 形成新的被除数
int current_dividend = x * 10 + a1[i];
// 存储当前位的商
c[i] = current_dividend / b;
// 更新余数
x = current_dividend % b;
}
// --- 步骤 C: 处理前导零与输出 ---
int lenc = 1;
// 跳过商的前导零,但如果商为 0,至少保留一位
while(c[lenc] == 0 && lenc < lena)
{
lenc++;
}
// 顺序输出商
for(int i = lenc; i <= lena; i++)
{
cout << c[i];
}
// 额外输出余数(不在原代码中,但这是高精度除法的重要结果)
// cout << " R " << x << endl;
return 0;
}
0 条评论
目前还没有评论...