【算法笔记】高精度计算

高精度计算

主要进行的是大整数的四大计算;
使用数组存储;
正确处理借位、进位。

高精度加法

要点: 逐位从地位到高位相加,处理进位

  • 题目描述 (Description)
    输入两个大整数a,b,输出他们的和。(1<=a,b<=10^100)

  • 输入格式(Format Input)
    输入两个大整数a和b。(1<=a,b<=10^100)
    输出格式(Format Output)
    输出a加b的和。

  • 样例(Sample)
    输入样例1 (Sample Input 1)
    43434343445435343 32435647668754353
    输出样例1 (Sample Output 1)
    75869991114189696

#include <bits/stdc++.h>
using namespace std;
char aa[1001], bb[1001];                         // 初始数据 
int c[1002], a[1001], b[1001], la, lb, lc;	// 数组c有可能产生进位 
/*
	aa, bb -- (char)用来收集输入的数据(0-n,高-低)
	a, b     -- (int)用来转换aa,bb数组(0-n,低-高),可以保证位数对齐
	c         -- 收集答案(a + b)
*/
int main()
{
	// 1. 初始化 -- 对设置的数组先初始化元素
	memset(a, 0, sizeof(a));
	memset(b, 0, sizeof(b));
	memset(c, 0, sizeof(c));
	scanf("%s %s", aa + 1, bb + 1);    // customize:从下标为1开始存储数据
	la = strlen(aa + 1); 
	lb = strlen(bb + 1);
	// 2. 位数对其(高位在后,低位在前) -- a, b
	for(int i = 1; i <= la; i++)
		a[i] = aa[la - i + 1] - '0';    // 转换成int类型
	for(int i = 1; i <= lb; i++)
		b[i] = bb[lb - i + 1] - '0';
	// 3. 加法计算,结果保存到数组c中
	// 计算数组c的长度 -- max(la, lb) 
	if(la > lb)	lc = la;
	else lc = lb;
    // lc = max(la, lb);
    // 计算每一位的结果
	for(int i = 1; i <= lc; i++)
	{
		c[i] = a[i] + b[i] + c[i];
		c[i + 1] += c[i] / 10;
		c[i] %= 10;
	}	
	// 4. 输出结果 
	// 判断c是否产生进位
	if(c[lc + 1] != 0)	lc++; 
	for(int i = 1; i <= lc; ++i)
	{
		cout << c[lc - i + 1];
	} 
	cout << endl;
	return 0;
}

高精度减法

要点: 逐位相减,处理退位

  • 题目描述 (Description)
    输入两个大整数a,b,输出他们的差。(1<=a,b<=10^100)

  • 输入格式(Format Input)
    输入两个大非负整数a和b。(1<=a,b<=10^100)

  • 输出格式(Format Output)
    输出a减b的差。

  • 样例(Sample)
    输入样例1 (Sample Input 1)
    复制
    35 45
    输出样例1 (Sample Output 1)
    -10

#include <bits/stdc++.h>
using namespace std;
char aa[10010], bb[10010];	// 初始数据 
int c[10010], a[10010], b[10010], la, lb, lc;
int main()
{
	// 1. 初始化 
	memset(a, 0, sizeof(a));
	memset(b, 0, sizeof(b));
	memset(c, 0, sizeof(c));
	scanf("%s %s", aa + 1, bb + 1);    // customize:从下标1开始保存数据
	la = strlen(aa + 1); 
	lb = strlen(bb + 1);
	// 2. 位数对其(高位在后,低位在前) 
	for(int i = 1; i <= la; i++)
		a[i] = aa[la - i + 1] - '0';
	for(int i = 1; i <= lb; i++)
		b[i] = bb[lb - i + 1] - '0';
	// 3. 判断a和b的大小
	bool flag = 1;	// 使用flag表示+/-
	if(la > lb)	   flag = 1;
	else if(la < lb)	flag = 0;
	else 
	{
		// la = lb
		for(int i = la; i > 0; i--)
		{
			if(a[i] > b[i])
			{
				flag = 1;
				break;	
			}
			else if(a[i] < b[i])
			{
				flag = 0;
				break;
			}
			// 若a和b一直相等,则flag保持不变,flag = 1
		} 
	}

	// 4. 减法计算,结果保存到数组c中
	// 判断正负
	if(flag == 0)
	{
		cout << "-";
		swap(a, b);	 	//交换数组 -- 保证 a > b 
		swap(la, lb);	    // 交换数组长度	
	} 
	
	// 计算数组c的长度 -- max(la, lb) 
	lc = max(la, lb);
	for(int i = 1; i <= lc; i++)
	{
		// 逐位计算 a-b
		c[i] = c[i] + a[i] - b[i];
		if(c[i] < 0)
		{
			c[i] += 10;		// 小 -大,借位 
			a[i + 1]--;		// 高位 - 1
		}
	}	
	// 4. 输出结果 
	// 退位 消除前导0 
	while(c[lc] == 0 && lc > 1)
		lc--;	// 从最高位开始,直到找到第一个不为0的数组元素 或结果为0 
	for(int i = lc; i > 0; i--)
	{
		cout << c[i];	
	} 
	cout << endl;
	return 0;
}

高精度乘法

要点:

#include <bits/stdc++.h>
using namespace std;
char ca[110], cb[110];		// 原始数据 
int a[110], b[110], c[210]; // 处理后的数据 
int main()
{
	// 1. 初始化 赋值 
	memset(a, 0, 110); 
	memset(b, 0, 110);
	memset(c, 0, 110);
	cin >> ca >> cb;
	int la = strlen(ca);
	int lb = strlen(cb);
	// 2. 位数对其(int) 
	for(int i = 0; i < la; ++i)
		a[la - i] = ca[i] - '0';
	for(int i = 0; i < lb; ++i)
		b[lb - i] = cb[i] - '0';
	
	// 3. 乘法计算 
	int lc = la + lb - 1;	// lc最多位数为 la + lb 位 
	for(int i = 1; i <= la; ++i)
	{
		// a从个位开始逐一和b的每一位相乘,最多影响2位 
		for(int j = 1; j <= lb; ++j)
		{
			// a[i] * b[j] 会影响c[i + j]和c[i + j - 1]两位 
			c[i + j - 1] += a[i] * b[j];
			c[i + j] += c[i + j - 1] / 10;
			c[i + j - 1] %= 10;
		}
	}
	if(c[lc + 1])	lc++;
	while(c[lc] == 0 && lc > 1)	lc--;
	for(int i = lc; i > 0; --i)	cout << c[i]; 
	return 0;
}

高精度除法(高精度除以低精度)

要点: 模拟短除法。

#include <bits/stdc++.h>
using namespace std;
char aa[110];
int a[110], c[110], b, x = 0;  // x -- 余数 
int main()
{
	// 1. 初始化 
	memset(a, 0, sizeof(a));
	memset(c, 0, sizeof(c));
	scanf("%s %d", aa + 1, &b);
	int la = strlen(aa + 1); 
	// 转换放入int型数组a中 
	for(int i = 1; i <= la; i++)
		a[i] = aa[i] - '0';
	// 2. 除法运算,将结果保存在数组c中 
	for(int i = 1; i <= la; i++)
	{
		c[i] = (x * 10 + a[i]) / b;  // 存储一位结果(高-->低) 
		x = (x * 10 + a[i]) % b;	 // 更新余数 
	}
	// 3. 去除前导0,保留个位数
	int lc = 1;
	// a / b结果最多可能有最多可能有la位,如果到la-1位都为0,则保留最后一位 
	while(c[lc] == 0 && lc < la)  lc++;
	// 4. 输出结果
	// 从lc开始往后输出,直到la(个位) 
	for(int i = lc; i <= la; i++)
		cout << c[i]; 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值