一、复习高低精度
一个数分为两种类型:
1. 高精度数,即一个长度特别长的数,使用 long long 也无法存储的一类数字。
2. 低精度数,即一个普通的数,可以使用 long long 来存储。
由于高精度除法比较简单,建议大家摸透了高精度加减法和高精度乘法的逻辑(戳蓝色文字进入课程快览)。
二、复习高精度乘法
1. 一共有两个 for 循环,第一个 for 循环遍历第一个因数,第二个 for 循环遍历第二个因数。
2. for 循环中的值分别是 j = 0 ~ lenb-1,i = 0 ~ lena-1。
3. 计算逻辑:
ans[i+j] = a[i] * b[j] + in + ans[i+j];
4. 输出:
【去前导零】while (ans[len_ans-1] == 0 && len_ans > 1) len_ans--;
【正常逆序输出】ans[len_ans-1] ~ ans[0]
三、存储的基础类型
输入的高精度被除数: char 类型
转换后的高精度被除数: int 类型
低精度除数: int 类型
高精度被除数的位数: int 类型
存储结果: char 类型
答案的长度: int 类型
四、输入与转换
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
// 存储并输入
char a_str[1005] = {};
int b;
cin >> a_str >> b;
// 转换
int a[1005] = {};
int len_a = strlen(a_str);
for (int i = 0; i <= len_a-1; i++)
{
a[i] = a_str[i] - 48; // 正序存储
}
return 0;
}
五、计算过程
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
// 存储并输入
char a_str[1005] = {};
int b;
cin >> a_str >> b;
// 转换
int a[1005] = {};
int len_a = strlen(a_str);
for (int i = 0; i <= len_a-1; i++)
{
a[i] = a_str[i] - 48; // 正序存储
}
// 计算
int len_ans = len_a; // 计算次数
int ans[1005] = {};
int rem = 0; // 余数
for (int i = 0; i <= len_ans-1; i++)
{
ans[i] = (rem * 10 + a[i]) / b; // 写商
rem = (rem * 10 + a[i]) % b; // 写余
}
// 去前导零
int k = 0; // k 表示第一个不为 0 元素的下标
while (ans[k] == 0 && k < len_ans-1)
{
k++;
}
// 正常正序输出
for (int i = k; i <= len_ans-1; i++)
{
cout << ans[i];
}
return 0;
}
看一下运行的效果:
六、小数点优化
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
// 存储并输入
char a_str[1005] = {};
int b;
int point = 3; // 保留小数的数位
cin >> a_str >> b;
// 转换
int a[1005] = {};
int len_a = strlen(a_str);
for (int i = 0; i <= len_a-1; i++)
{
a[i] = a_str[i] - 48; // 正序存储
}
// 计算
int len_ans = len_a; // 计算次数
int ans[2100] = {};
int rem = 0; // 余数
for (int i = 0; i <= len_ans+point-1; i++)
{
ans[i] = (rem * 10 + a[i]) / b; // 写商
rem = (rem * 10 + a[i]) % b; // 写余
}
// 去前导零
int k = 0; // k 表示第一个不为 0 元素的下标
while (ans[k] == 0 && k < len_ans-1)
{
k++;
}
// 正常正序输出整数部分
for (int i = k; i <= len_ans-1; i++)
{
cout << ans[i];
}
// 小数点后判断
if (point > 0)
{
cout << ".";
for (int i = len_ans; i <= len_ans+point-1; i++)
{
cout << ans[i];
}
}
return 0;
}
附录:两数的平均数
#incldue <iostream>
#include <cstring>
using namespace std;
int main()
{
// 高精度加法
// 输入并存储
char a_str[1005] = {};
char b_str[1005] = {};
cin >> a_str >> b_str;
int a[1005] = {};
int b[1005] = {};
int len_a = strlen(a_str);
int len_b = strlen(b_str);
for (int i = 0; i <= len_a-1; i++)
{
a[len_a-i-1] = a_str[i] = 48;
}
for (int i = 0; i <= len_b-1; i++)
{
b[len_b-i-1] = b_str[i] = 48;
}
// 计算
int sum[1005] = {};
int len_sum = max(len_a, len_b);
int in = 0;
for (int i = 0; i <= len_sum-1; i++)
{
sum[i] = a[i] + b[i] + in;
in = sum[i] / 10;
sum[i] %= 10;
}
// 最高位判断
if (in)
{
sum[len_sum] = in;
len_sum++;
}
// 高精度除法
int divid[1005] = {};
// 正序存储
for (int i = 0; i <= len_sum-1; i++)
{
divid[len_sum-i-1] = sum[i];
}
// 计算
int len_ans = len_sum;
int ans[1005] = {};
int rem = 0;
for (int i = 0; i <= len_ans-1; i++)
{
ans[i] = (rem * 10 + divid[i]) / 2;
rem = (rem * 10 + divid[i]) % 2;
}
// 去前导零
int k = 0;
while (ans[k] == 0 && k < len_ans-1)
{
k++;
}
// 输出平均数
for (int i = k; i <= len_ans-1; i++)
{
cout << ans[i];
}
return 0;
}