C++知识点总结(7):玩转高精度除法

一、复习高低精度

一个数分为两种类型:

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 
#include 
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 
#include 
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;
}

C++知识点总结(7):玩转高精度除法_第1张图片

看一下运行的效果:

C++知识点总结(7):玩转高精度除法_第2张图片

六、小数点优化

#include 
#include 
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 
#include 
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; 
}

你可能感兴趣的:(C/C++,高精度计算,算法)