[C++] 高精度加法(作用 + 模板 + 例题)

高精度加法-目录

高精度加法用途

高精度加法通常用于加很大的数(真的很大, 超unsigned long long的那种).

高精度加法模板

注: 本篇数组下标0(x[0])存储的是该数组的有效位数.

string转数位数组

我们一般使用string类型存储很大的数.

这个时候, 高精度加法要干的是模拟列竖式, 把每一位加起来, 然后再考虑进位的问题 . 模拟列竖式需要数位末尾对齐 , 所以我们最好把原始数据反转一下.

考虑以上两点, 需要先把string转换成int数位数组. 在这里我们以普通int数组举例, 除此之外还能用vector或者short数组或者继续用string也行.

cpp 复制代码
// 头文件
#include <iostream>
#include <string>
using namespace std;

// **** 重点!!! ****
// 一般我们用'2'表示英语单词'to'
void s2BIG(string s, int a[]){
	int len = s.size();
	for(int i = 1; i <= len; i++){
		a[i] = s[len - i] - '0';
	}
	a[0] = len;
}

// 使用方法
int main(){
	string s;
	cin >> s;
	s2BIG(s, A);
	// ......
	return 0;
}

int 转数位数组(附加型知识点)

这是一个特殊的点, 因为有时候我们要把int和所谓的BIG进行高精度运算, 这时我们需要把int转换为BIG(数位数组) .通过while拆位实现.

cpp 复制代码
void i2BIG(int n, int a[]){
	int cur = 0;
	while(n > 0){
		cur++;
		a[cur] = n % 10;
		n /= 10;
	}
	if(cur == 0) cur++;
	a[0] = cur;
}

后续代码会把这段加上, 但可能不会再用.


高精度输出

我们先把辅助的代码讲完. 我们完成加法后, 我们肯定要把它输出出来, 由于是反着计算的, 所以要反着输出. 这个时候我们就需要高精度输出. 我们实现的功能是把进入函数的数组反向输出 .

本段代码整合了上一段的代码.

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

int a[1005];

void s2BIG(string s, int a[]){
	int len = s.size();
	for(int i = 1; i <= len; i++){
		a[i] = s[len - i] - '0';
	}
	a[0] = len;
}

void i2BIG(int n, int a[]){
	int cur = 0;
	while(n > 0){
		cur++;
		a[cur] = n % 10;
		n /= 10;
	}
	if(cur == 0) cur++;
	a[0] = cur;
}

void printBIG(int a[]){
	int len = a[0];
	for(int i = len; i > 0; i--){
		cout << a[i];
	}
	cout << endl;
}

int main(){
	string s;
	cin >> s;
	s2BIG(s, a);
	printBIG(a);
	return 0;
}

高精度加法

分为以下部分:

  • 写入有效长度
  • 对应位数求和
  • 处理进位情况
  • 根据最高位更新长度
cpp 复制代码
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

int x[1005], y[1005], z[1005];

void s2BIG(string s, int a[]){
	int len = s.size();
	for(int i = 1; i <= len; i++){
		a[i] = s[len - i] - '0';
	}
	a[0] = len;
}

void i2BIG(int n, int a[]){
	int cur = 0;
	while(n > 0){
		cur++;
		a[cur] = n % 10;
		n /= 10;
	}
	if(cur == 0) cur++;
	a[0] = cur;
}

void printBIG(int a[]){
	int len = a[0];
	for(int i = len; i > 0; i--){
		cout << a[i];
	}
	cout << endl;
}

/**** 新增 ****/
void addBIG(int x[], int y[], int z[]){
	z[0] = max(x[0], y[0]);				// 先写出有效长度
	for(int i = 1; i <= z[0]; i++)		// 对应位求和
		z[i] = x[i] + y[i];
	for(int i = 1; i <= z[0]; i++){		// 处理进位
		z[i + 1] += z[i] / 10;
		z[i] %= 10;
		if(z[z[0] + 1] != 0)			// 处理最高位进位, 更新有效位数
			z[0]++;
	}
}

int main(){
	string a, b;
	cin >> a >> b;
	s2BIG(a, x);
	s2BIG(b, y);
	addBIG(x, y, z);
	printBIG(z);
	return 0;
}

函数大合集!!!

cpp 复制代码
void s2BIG(string s, int a[]){
	int len = s.size();
	for(int i = 1; i <= len; i++){
		a[i] = s[len - i] - '0';
	}
	a[0] = len;
}

void i2BIG(int n, int a[]){
	int cur = 0;
	while(n > 0){
		cur++;
		a[cur] = n % 10;
		n /= 10;
	}
	if(cur == 0) cur++;
	a[0] = cur;
}

void printBIG(int a[]){
	int len = a[0];
	for(int i = len; i > 0; i--){
		cout << a[i];
	}
	cout << endl;
}

void addBIG(int x[], int y[], int z[]){
	z[0] = max(x[0], y[0]);				// 先写出有效长度
	for(int i = 1; i <= z[0]; i++)		// 对应位求和
		z[i] = x[i] + y[i];
	for(int i = 1; i <= z[0]; i++){		// 处理进位
		z[i + 1] += z[i] / 10;
		z[i] %= 10;
		if(z[z[0] + 1] != 0)			// 处理最高位进位, 更新有效位数
			z[0]++;
	}
}
相关推荐
想不明白的过度思考者2 分钟前
数据结构(排序篇)——七大排序算法奇幻之旅:从扑克牌到百亿数据的魔法整理术
数据结构·算法·排序算法
小七rrrrr8 分钟前
动态规划法 - 53. 最大子数组和
java·算法·动态规划
code小毛孩13 分钟前
leetcodehot100 矩阵置零
算法
何妨重温wdys22 分钟前
矩阵链相乘的最少乘法次数(动态规划解法)
c++·算法·矩阵·动态规划
重启的码农23 分钟前
ggml 介绍 (6) 后端 (ggml_backend)
c++·人工智能·神经网络
重启的码农24 分钟前
ggml介绍 (7)后端缓冲区 (ggml_backend_buffer)
c++·人工智能·神经网络
常利兵31 分钟前
Kotlin作用域函数全解:run/with/apply/let/also与this/it的魔法对决
android·开发语言·kotlin
姜不吃葱35 分钟前
【力扣热题100】双指针—— 接雨水
数据结构·算法·leetcode·力扣热题100
PineappleCoder39 分钟前
大小写 + 标点全搞定!JS 如何精准统计单词频率?
前端·javascript·算法
雨落倾城夏未凉44 分钟前
5.通过拷贝构造函数复制一个对象,假如对象的成员中有个指针类型的变量,如何避免拷贝出来的副本中的该成员之下行同一块内存(等价于默认拷贝构造函数有没有缺点)
c++·后端