【算法】高精度算法(加减乘除)

文章目录

1、高精度加法

1.1、思路步骤

①用字符存放高精度数

cpp 复制代码
	string s1, s2;
	cin >> s1 >> s2;

②将每位数字倒序存入数组中

cpp 复制代码
	//将s1倒序存入a1中,将s2倒序存入a2中
	for (int i = 0; i < s1.length(); i++)
	{
		a1[i] = s1[s1.length() - i - 1] - '0';//将字符转化为数字
	}
	for (int i = 0; i < s2.length(); i++)
	{
		a2[i] = s2[s2.length() - i - 1] - '0';
	}

③顺序将数组中的每位数字进行相加

cpp 复制代码
	//相加
	int len = s1.length() > s2.length() ? s1.length() : s2.length();
	for (int i = 0; i < len; i++)
	{
		a3[i] = a1[i] + a2[i];
	}

④相加后的数字>=10进行进位操作

cpp 复制代码
	//>=10进一
	for (int i = 0; i < len; i++)
	{
		if (a3[i] >= 10)
		{
			a3[i + 1] += a3[i] / 10;
			a3[i] %= 10;
		}
	}

⑤判断最后一位是否不为0,不为0说明相加后有增位,len+1(结果数组的长度增一)

cpp 复制代码
	if (a3[len] != 0)
	{
		len++;
	}

⑥倒序输出数组的每位

cpp 复制代码
//逆序输出a3结果
	for (int i = len - 1; i >= 0; i--)
	{
		cout << a3[i];
	}

1.2、代码

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1, s2;//存放两高精度数
	cin >> s1 >> s2;
	//数组长度要大于位数
	int a1[210] = { 0 };
	int a2[210] = { 0 };//存放要进行运算的两数
	int a3[210] = { 0 };//存放结果

	//将s1倒序存入a1中,将s2倒序存入a2中
	for (int i = 0; i < s1.length(); i++)
	{
		a1[i] = s1[s1.length() - i - 1] - '0';//将字符转化为数字
	}
	for (int i = 0; i < s2.length(); i++)
	{
		a2[i] = s2[s2.length() - i - 1] - '0';
	}

	//相加
	int len = s1.length() > s2.length() ? s1.length() : s2.length();
	for (int i = 0; i < len; i++)
	{
		a3[i] = a1[i] + a2[i];
	}

	//>=10进一
	for (int i = 0; i < len; i++)
	{
		if (a3[i] >= 10)
		{
			a3[i + 1] += a3[i] / 10;
			a3[i] %= 10;
		}
	}
	if (a3[len] != 0)
	{
		len++;
	}

	//逆序输出a3结果
	for (int i = len - 1; i >= 0; i--)
	{
		cout << a3[i];
	}
	return 0;
}

2、高精度减法

2.1、思路步骤

①用字符存放高精度数

cpp 复制代码
	string s1, s2;
	cin >> s1 >> s2;

②判断大小

cpp 复制代码
	//判断大小,让s1始终>s2
	char flag = '+';
	if (s1.length() < s2.length() || (s1.length() == s2.length() && s1 < s2))
	{
		swap(s1, s2);
		flag = '-';   //输入的s1-s2<0,进行计算的是s2-s1(大-小)
	}

③将每位数字倒序存入数组中

cpp 复制代码
	//将s1倒序存入a1中,将s2倒序存入a2中
	for (int i = 0; i < s1.length(); i++)
	{
		a1[i] = s1[s1.length() - i - 1] - '0';//将字符转化为数字
	}
	for (int i = 0; i < s2.length(); i++)
	{
		a2[i] = s2[s2.length() - i - 1] - '0';
	}

④顺序将数组中的每位数字进行相减

cpp 复制代码
	//相减
	for (int i = 0; i < s1.length(); i++)
	{
		//借位
		if (a1[i] < a2[i])
		{
			a1[i] += 10;
			a1[i + 1] -= 1;
		}
		a3[i] = a1[i] - a2[i];
	}

④判断a3开始遍历的末位下标

cpp 复制代码
	//判断a3开始遍历的末位下标
	int index = 0;
	for (int i = s1.length() - 1; i >= 0; i--)
	{
		if (a3[i] != 0)
		{
			index = i;
			break;
		}
	}

⑤倒序输出数组的每位

cpp 复制代码
	//倒序输出a3
	if (flag == '-')
		cout << flag;
	for (int i = index; i >= 0; i--)
	{
		cout << a3[i];
	}

2.2、代码

cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
	string s1, s2;
	cin >> s1 >> s2;
	int a1[210] = { 0 };
	int a2[210] = { 0 };
	int a3[210] = { 0 };

	//判断大小,让s1始终>s2
	char flag = '+';
	if (s1.length() < s2.length() || (s1.length() == s2.length() && s1 < s2))
	{
		swap(s1, s2);
		flag = '-';   //输入的s1-s2<0,进行计算的是s2-s1(大-小)
	}

	//将s1倒序存入a1中,将s2倒序存入a2中
	for (int i = 0; i < s1.length(); i++)
	{
		a1[i] = s1[s1.length() - i - 1] - '0';//将字符转化为数字
	}
	for (int i = 0; i < s2.length(); i++)
	{
		a2[i] = s2[s2.length() - i - 1] - '0';
	}

	
	//相减
	for (int i = 0; i < s1.length(); i++)
	{
		//借位
		if (a1[i] < a2[i])
		{
			a1[i] += 10;
			a1[i + 1] -= 1;
		}
		a3[i] = a1[i] - a2[i];
	}

	//判断a3开始遍历的末位下标
	int index = 0;
	for (int i = s1.length() - 1; i >= 0; i--)
	{
		if (a3[i] != 0)
		{
			index = i;
			break;
		}
	}

	//倒序输出a3
	if (flag == '-')
		cout << flag;
	for (int i = index; i >= 0; i--)
	{
		cout << a3[i];
	}
	return 0;
}

3、高精度乘法

①高精度*单精度

1、思路步骤

①用字符存放高精度数

cpp 复制代码
string s;
int a[210] = {0};//高精度数
int b = 0;//单精度数(0<=b<10000)
cin >> s >> b;

②将每位数字倒序存入数组中

cpp 复制代码
//将s逆序存入a中
for (int i = 0; i < s.length(); i++)
{
	a[i] = s[s.length() - i - 1] - '0';
}

③a的每一位与b相乘

cpp 复制代码
//a的每一位与b相乘
for (int i = 0; i < s.length(); i++)
{
	a[i] *= b;
}

④将a中>=10的进行进位操作

cpp 复制代码
//将a中>=10的进行进位操作(相乘之后的位数不超过s的长度+b的长度)
for (int i = 0; i < s.length() + 4; i++)
{
	if (a[i] >= 10)
	{
		a[i + 1] += a[i] / 10;
		a[i] %= 10;
	}
}

⑤找到开始输出的下标

cpp 复制代码
//找到开始输出的下标
int index = 0;
for (int i = s.length() + 4 - 1; i >= 0; i--)
{
	if (a[i] != 0)
	{
		index = i;
		break;
	}
}

⑥倒序输出数组的每位

cpp 复制代码
//逆序输出a[i]
for (int i = index; i >= 0; i--)
{
	cout << a[i];
}

2、代码

cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
	//1、高精度数*单精度数(0<=b<10000)

	string s;
	int a[210] = {0};//高精度数
	int b = 0;//单精度数
	cin >> s >> b;

	//将s逆序存入a中
	for (int i = 0; i < s.length(); i++)
	{
		a[i] = s[s.length() - i - 1] - '0';
	}
	//a的每一位与b相乘
	for (int i = 0; i < s.length(); i++)
	{
		a[i] *= b;
	}
	//将a中>=10的进行进位操作(相乘之后的位数不超过s的长度+b的长度)
	for (int i = 0; i < s.length() + 4; i++)
	{
		if (a[i] >= 10)
		{
			a[i + 1] += a[i] / 10;
			a[i] %= 10;
		}
	}
	//找到开始输出的下标
	int index = 0;
	for (int i = s.length() + 4 -1; i >= 0; i--)
	{
		if (a[i] != 0)
		{
			index = i;
			break;
		}
	}
	//逆序输出a[i]
	for (int i = index; i >= 0; i--)
	{
		cout << a[i];
	}
	return 0;
}

②高精度*高精度

1、思路步骤

①用字符存放高精度数

cpp 复制代码
string s1, s2;
int a1[210] = { 0 };
int a2[210] = { 0 };
int a3[420] = { 0 };//存放结果
cin >> s1 >> s2;

②将每位数字倒序存入数组中

cpp 复制代码
//将s1倒序存入a1中,将s2倒序存入a2中
for (int i = 0; i < s1.length(); i++)
{
	a1[i] = s1[s1.length() - i - 1] - '0';//将字符转化为数字
}
for (int i = 0; i < s2.length(); i++)
{
	a2[i] = s2[s2.length() - i - 1] - '0';
}

③a1的每一位与a2的每一位相乘

cpp 复制代码
//a1的每一位与a2的每一位相乘
for (int i = 0; i < s1.length(); i++)
{
	for (int j = 0; j < s2.length(); j++)
	{
		a3[j + i] += a1[i] * a2[j];	//错位相加
		//进位
		if (a3[j + i] >= 10)
		{
			a3[j + i + 1] += a3[j + i] / 10;
			a3[j + i] %= 10;
		}
	}
}

④找a3末位下标

cpp 复制代码
//找a3末位下标
int index = 0;
for (int i = s1.length() + s2.length() - 1; i >= 0; i--)
{
	if (a3[i] != 0)
	{
		index = i;
		break;
	}
}

⑤逆序输出a3

cpp 复制代码
//逆序输出a3
for (int i = index; i >= 0; i--)
{
	cout << a3[i];
}

2、代码

cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
	//2、高精度数*高精度数
	string s1, s2;
	int a1[210] = { 0 };
	int a2[210] = { 0 };
	int a3[420] = { 0 };//存放结果
	cin >> s1 >> s2;

	//将s1倒序存入a1中,将s2倒序存入a2中
	for (int i = 0; i < s1.length(); i++)
	{
		a1[i] = s1[s1.length() - i - 1] - '0';//将字符转化为数字
	}
	for (int i = 0; i < s2.length(); i++)
	{
		a2[i] = s2[s2.length() - i - 1] - '0';
	}
	//a1的每一位与a2的每一位相乘
	for (int i = 0; i < s1.length(); i++)
	{
		for (int j = 0; j < s2.length(); j++)
		{
			a3[j + i] += a1[i] * a2[j];	//错位相加
			//进位
			if (a3[j + i] >= 10)
			{
				a3[j + i + 1] += a3[j + i] / 10;
				a3[j + i] %= 10;
			}
		}
	}
	//找a3末位下标
	int index = 0;
	for (int i = s1.length() + s2.length() - 1; i >= 0; i--)
	{
		if (a3[i] != 0)
		{
			index = i;
			break;
		}
	}
	//逆序输出a3
	for (int i = index; i >= 0; i--)
	{
		cout << a3[i];
	}
	return 0;
}

练习:求2^n

cpp 复制代码
//高精度算法:计算2的n次方
#include <iostream>
using namespace std;
int a[100000]={0};
int main (){
    int n,x=0,len=1;
    cin>>n;
    a[1] = 1; 
    for(int i=0;i<n;i++){
        for(int j=1;j<=len;j++){
            a[j] = a[j]*2+x;
            x=a[j]/10;
            a[j]%=10;
            if(x!=0 && j==len) 
            	len++;
        }
    }
    for(int i=len;i>=1;i--) 
    	cout<<a[i];
    return 0;
}

4、高精度除法

①单精度/单精度

cpp 复制代码
#include<iostream>
using namespace std;
int main()
{
	//1、单精度/单精度
	int a;//被除数
	int b;//除数
	int n;//保留n位小数
	cin >> a >> b >> n;

	//整数部分
	cout << a / b << '.';
	//小数部分
	int t = a % b;//初始化余数
	for (int i = 0; i < n; i++)
	{
		t *= 10;
		cout << t / b;
		t %= b;
	}
	return 0;
}

②高精度/单精度

cpp 复制代码
#include<iostream>
using namespace std;
int main()
{
	//2、高精度/单精度
	string s;//被除数
	int b;//除数
	cin >> s >> b;
	int a[255] = { 0 };
	int c[255] = { 0 };//商
	int t = 0;//余数

	for (int i = 0; i < s.size(); i++)
	{
		a[i] = s[i] - '0';
	}
	for (int i = 0; i < s.size(); i++)
	{
		t = t * 10 + a[i];
		if (a[i] > b)
		{
			c[i] = t / b;
			t %= b;
		}
		else {
			c[i] = 0;
		}
	}
	int index = 0;
	for (int i = 0; i < s.size(); i++)
	{
		if (c[i] != 0)
		{
			index = i;
			break;
		}
	}
	for (int i = index; i < s.size(); i++)
	{
		cout << c[i];
	}
	cout << "......" << t; //输出余数
	return 0;
}

③高精度/高精度

cpp 复制代码
#include<iostream>
using namespace std;
void cpy(int* x, int* y, int offset)
{
	for (int i = 1; i <= x[0]; i++)
	{
		y[i + offset] = x[i];
	}
	y[0] = x[0] + offset;
}
//比较数组大小
bool comp(int* x, int* y)
{
	if (x[0] > y[0])
		return true;
	if (x[0] < y[0])
		return false;
	if (x[0] == y[0])
	{
		for (int i = 1; i <= x[0]; i++)
		{
			if (x[i] > y[i])
				return true;
			if (x[i] < y[i])
				return false;
		}
	}
	return true;
}
//两数组相减
void sub(int* x, int* y)
{
	for (int i = x[0]; i >=1; i--)
	{
		if (x[i] < y[i])
		{
			x[i] = x[i] + 10;
			x[i - 1] = x[i - 1] - 1;
		}
		x[i] = x[i] - y[i];
	}
}
int main()
{
	//3、高精度/高精度
	string s1, s2;//被除数、除数
	int a[255] = { 0 };
	int b[255] = { 0 };
	int c[255] = { 0 };//商
	cin >> s1 >> s2;
	a[0] = s1.size();
	b[0] = s2.size();
	for (int i = 1; i <= a[0]; i++)
	{
		a[i] = s1[i - 1] - '0';
	}
	for (int i = 1; i <= b[0]; i++)
	{
		b[i] = s2[i - 1] - '0';
	}
	c[0] = a[0] - b[0] + 1;//商的位数
	int t[500] = { 0 };//除数临时数组
	for (int i = 1; i <= c[0]; i++)
	{
		memset(t, 0, sizeof(t));
		cpy(b, t, i - 1);//把b数组复制到临时数组t中
		a[0] = t[0];
		while (comp(a, t))
		{
			sub(a, t);
			c[i]++;
		}
	}
	int index = 1;
	while (c[index] == 0 && index < c[0])
		index++;
	for (int i = index; i <=c[0]; i++)
	{
		cout << c[i];
	}
	return 0;
}
相关推荐
树獭叔叔2 小时前
内存价格被Google打下来了?: TurboQuant对KVCache的量化
算法·aigc·openai
echome8882 小时前
Python 装饰器实战:用@syntax 优雅地增强函数功能
开发语言·python
旖-旎2 小时前
前缀和(矩阵区域和)(8)
c++·算法·leetcode·前缀和·动态规划
Vect__2 小时前
基于CSAPP深刻理解编译链接过程
linux·c++
¥-oriented2 小时前
数据集资源
笔记
月落归舟2 小时前
排序算法---(一)
数据结构·算法·排序算法
biuyyyxxx2 小时前
Power Query功能区 - 主页
笔记·学习·excel
今儿敲了吗2 小时前
DS-3 循环队列判断队满
数据结构·笔记·学习
卷Java2 小时前
Python字典:键值对、get()方法、defaultdict,附通讯录实战
开发语言·数据库·python