高精度算法

大家都知道在c++中不同数据类型都有自己的取值范围

类型 字节 取值范围
int 4 -2^31 ~ 2^31 - 1
long long 8 -2^63 ~ 2^63 - 1
char 1 -2^7 ~ 2^7 - 1

当我们计算特别大的数据时,如果超过了int,甚至是long long的取值范围时,这时就没有合适的变量去运算,这是我们就需要用到高精度算法,顾名思义,高精度算法可以将特别大的数据进行运算,下面我们来看一下

高精度加法

高精度加法的思路和我们刚开始接触加法时的竖式运算一样
1234 + 456 1690 \begin{array}{r} 1234\\ +456\\ \hline 1690 \end{array} 1234+4561690
从个位开始相加,满十进一,加到最高位为止

代码思路:普通数据类型取值范围太小,我们采用数组的方式进行存储。首先定义两个string类s1,s2接受读入的两个数,因为运算时是采用从个位开始运算,所以我们将读入的两个数倒序输入进整形数组a,b中,转化是添加-‘0’将字符类型转换为整形。用一个数组c来记录结果。我们所需要运算的次数就是两个数中位数最多的那个数,定义了len来记录,然后将两个数位数对齐相加,再来一个循环判断是否需要进位,如果大于十就进位,最后将数组c倒序输出即可。

代码实现

#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
   
	string s1, s2;
	int a[3000], b[3000], c[3000] = {
   0};
	cin >> s1 >> s2;
	for(int i = 0; i < s1.size(); i++){
   
		a[s1.size() - i - 1] = s1[i] - '0';
	}
	for(int i = 0; i < s2.size(); i++){
   
		b[s2.size() - i - 1] = s2[i] - '0';
	}
	int len = max(s1.size(), s2.size());
	for(int i = 0; i <= len ; i++)
	  c[i] = a[i] + b[i];
	for(int i = 0; i <= len; i++){
   
		if(c[i] >= 10)
		{
   
			c[i + 1] = c[i + 1] + c[i] / 10;
			c[i] = c[i] % 10;  
		}
	}
	if(c[len] != 0)
	  len++;
	for(int i = len - 1; i >= 0; i--)
	  cout << c[i];
	return 0;
 } 
 

高精度减法

高精度减法思路和高精度加法思路大致一样,都是采用竖式计算的思想。

我们知道10-1=9 1-10=-9 两个数一样,当减数和被减数的位置调换后,结果知识正负号改变,在进行减法运算时,我们可以在读入数据时比较一下两个数的大小,始终将大数放在前面进行运算。

代码思路:跟高精度加法类似,先定义数组,然后读入数据。定义一个flag来记录结果符号,读入数据后判断一下s1和s2的大小,始终将大数放在前面。然后逆序读入数组a,b中,因为计算的次数就是最大那个数的位数(s1的位数),然后我们进行运算,每一次运算都判断啊a[i]b[i]的大小,如果被减数小于减数,被减数借一当十,高位a[i+1]减去1,然后相减的结果存入数组c中。运算后,我们还需要判断一下结果的位数,定义find用来记录,用一个循环找到数组c的位数。最后倒序输出数组c即可。

代码实现

#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
   
	string s1, s2;
	int a[30000] = {
   0}, b[30000] = {
   0}, c[30000] = {
   0};
	cin >> s1 >> s2;
	char flag = '+';
	if(s1.size() < s2.size() || (s1.size() == s2.size() && s1 < s2))
	{
   
		swap(s1,s2);
		flag = '-';
	}
	for(int i = 0; i < s1.size(); i++)
	  a[s1.size() - i - 1] = s1[i] - '0';
	for(int i = 0; i < s2.size(); i++)
	  b[s2.size() - i - 1] = s2[i] - '0';
	for(int i = 0; i < s1.size(); i++)
	{
   
		if(a[i] < b[i])
		{
   
			a[i] += 10;
			a[i + 1] -= 1;
		}
		c[i] = a[i] - b[i]; 
	}
	if(flag == '-')
	  cout << flag;
	int find = 0;
	for(int i = s1.size() - 1; i >= 0; i--)
	{
   
		if(c[i] != 0)
		{
   
			find = i;
			break;
		}
	}
	for(int i = find; i >= 0; i--)
	  cout << c[i];
	return 0;
}

高精度乘法

高精度乘法运算有着差不多的思想,需要注意的是每次乘积的结果所在的位置,根据下图的公式可以找到规律a[i] * b[i] 对应 c[i + j + 1] 的位置,然后注意一下进位就行。

在这里插入图片描述

代码思路:首先读入数字,将数字逆序存入整形数组中,用双重循环进行运算,将a[i] * b[i]得到的结果存入到c[i + j]中,运算对进位处理,遍历整个数组c,如果大于等于10,进位。然后用while循环去掉前导零,最后倒序输出即可

代码实现

#include<iostream>

using namespace std;

int main()
{
   
	string s1, s2;
	int a[300000], b[300000], c[300000];
	cin >> s1 >> s2;
	int len = s1.size() + s2.size();
	for(int i = 0; i < s1.size(); i++)
	  a[s1.size() - i - 1] = s1[i] - '0';
	for(int i = 0; i < s2.size(); i++)
	  b[s2.size() - i - 1] = s2[i] - '0';	  
	for(int i = 0; i < s1.size(); i++)
	{
   
		for(int j = 0; j < s2.size(); j++)
		{
   
			c[i + j] += a[i] * b[j];
		}
	}
	for(int i = 0; i < len; i++)
	{
   
		if(c[i] >= 10)
		{
   
			c[i + 1] += c[i] / 10;
			c[i] %= 10;
		}
	}
	while(c[len] == 0 && len > 0)
	  len--;
	for(int i = len; i >= 0; i--)
	  cout << c[i];
	return 0;
}

高精度除法

高精度除法用一个大数除一个小数采用逐位试商法

在这里插入图片描述

代码思路:跟其他高精度一样,先读入。因为除法运算是从左到右进行的,所以不需要倒序输入进数组中。运算部分每次用大数的第i位除除数,然后利用x每次乘十加上a[i]完成进位。运算后用一个while循环出去前导零,最后输出结果即可。

代码实现

#include<iostream>

using namespace std;

string s1;
long long b, x, a[5005],c[5005];

int main()
{
   
	cin >> s1 >> b;
	int len = s1.size();
	for(int i = 1; i <= len; i++)
	  a[i] = s1[i - 1] - '0';
	for(int i = 1; i <= len; i++)
	{
   
		c[i] = (x * 10 + a[i]) / b;
		x = (x *10 + a[i]) % b;
	}
	int find = 1;
	while(c[find] == 0 && find < len)
	  find++;
	for(int i = find; i <= len; i++)
	  cout << c[i];
	return 0;
 } 

相关推荐

  1. 精度算法

    2024-02-15 14:50:02       19 阅读
  2. 精度模拟算法

    2024-02-15 14:50:02       11 阅读
  3. 基础算法-精度加法 基础算法-精度加法

    2024-02-15 14:50:02       26 阅读
  4. 算法精度(string实现)

    2024-02-15 14:50:02       11 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-15 14:50:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-15 14:50:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-15 14:50:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-15 14:50:02       20 阅读

热门阅读

  1. openJudge | 过滤多余的空格 C语言

    2024-02-15 14:50:02       29 阅读
  2. 【数据结构与算法】判断二叉树是否完全二叉树

    2024-02-15 14:50:02       31 阅读
  3. Shell脚本——提取目录名和文件名

    2024-02-15 14:50:02       27 阅读
  4. C#面:什么是托管代码(受管制的代码)?

    2024-02-15 14:50:02       33 阅读
  5. LeetCode879. Profitable Schemes——动态规划

    2024-02-15 14:50:02       29 阅读
  6. [缓存] - 3.金融交易系统缓存架构设计

    2024-02-15 14:50:02       28 阅读
  7. 【for循环——讲解】

    2024-02-15 14:50:02       29 阅读
  8. LED照明

    2024-02-15 14:50:02       25 阅读
  9. CCF-CSP 202206-2 寻宝!大冒险!

    2024-02-15 14:50:02       28 阅读
  10. 网络安全产品之认识蜜罐

    2024-02-15 14:50:02       34 阅读
  11. 七种SQL进阶用法

    2024-02-15 14:50:02       28 阅读
  12. conda env退回到之前的版本

    2024-02-15 14:50:02       24 阅读
  13. ubuntu下conda如何设置镜像源(清华镜像源)

    2024-02-15 14:50:02       30 阅读