高精度计算

一、为什么需要高精度计算?

  1. 常见数据类型及其范围
数据类型 存储大小 数值范围
short 2 Byte -32,768 ~ 32,767 (-2¹⁵ ~ 2¹⁵-1)
int 4 Byte -2,147,483,648 ~ 2,147,483,647 (-2³¹ ~ 2³¹-1)
long long 8 Byte -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 (-2⁶³ ~ 2⁶³-1)
float 4 Byte ≈ -10³⁸ ~ 10³⁸ (精度约6-7位小数)
double 8 Byte ≈ -10³⁰⁸ ~ 10³⁰⁸ (精度约15-16位小数)
char 1 Byte -128 ~ 127
  1. 高精度计算定义

当参与运算的数值范围超出标准数据类型的表示能力时,需要使用特殊方法进行运算,这就是高精度计算。

想象你要计算:

12345678901234567890 + 98765432109876543210

这个数字太大了,连long long(能存19位数字)都存不下,这时候就需要高精度计算。


二、高精度计算的基本思路

就像我们小学学的竖式计算一样:

  1. 用字符串存大数:因为字符串可以存很长的数字

    • 例如:"12345678901234567890"
  2. 倒着存储数字:方便计算时对齐个位

    • "12345" → 存成[5,4,3,2,1]
  3. 逐位计算:像列竖式一样一位一位算

  4. 结果再倒回来:把结果再倒过来变成正常顺序


三、四则运算的简单思路

加法
  1. 对齐位数
  2. 逐位相加
  3. 处理进位
#include <bits/stdc++.h>
using namespace std;

int a[300], b[300], c[500], len;
string s1, s2;

int main(){
    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';
	if(s1.size() > s2.size())
		len = s1.size();
	else
		len = 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] / 10;
			c[i] %= 10;
		}
	if(c[len] != 0)
		len++;
	for(int i = len - 1; i >= 0; i--)
		printf("%d", c[i]);
	return 0;
}
减法
  1. 比较大小确定符号
  2. 大数减小数
  3. 处理借位
#include <bits/stdc++.h>
using namespace std;

int a[300], b[300], c[300], len, p;
string s1, s2;

int main(){
	cin >> s1 >> s2;
	if((s1.size() < s2.size())||((s1.size() == s2.size())&&(s1 < s2))){
		printf("-");
		swap(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';
	len = s1.size();
	for(int i = 0; i < len; i++){
		if(a[i] < b[i]){
			a[i + 1]--;
			a[i] += 10;
		}
		c[i] = a[i] - b[i];
	}
	for(int i = len - 1; i >= 0; i--)
		if(c[i] != 0){
			p = i;
			break;
		}
	for(int i = p; i >= 0; i--)
		printf("%d", c[i]);
	return 0;
}
乘法
  1. 双重循环逐位相乘
  2. 累加部分积
  3. 处理进位
#include <bits/stdc++.h>
using namespace std;

int a[300], b[300], c[500], p;
string s1, s2;

int main() {
	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';
	for(int i = 0; i < s1.size(); i++)
		for(int j = 0; j < s2.size(); j++){
			c[i + j] += a[i] * b[j];
			if(c[i + j] >= 10){
				c[i + j + 1] += c[i + j] / 10;
				c[i + j] %= 10;
			}
		}
	for(int i = s1.size() + s2.size() - 1; i >= 0; i--)
		if(c[i] != 0){
			p = i;
			break;
		}
	for(int i = p; i >= 0; i--)
		printf("%d", c[i]);
	return 0;
}
除法
#include <bits/stdc++.h>
using namespace std;

int a, b, n, r;

int main(){
    scanf("%d%d%d", &a, &b, &n);
    printf("%d.", a / b);
    r = a % b;
    for(int i = 1; i <= n; i++){
    	r *= 10;
    	printf("%d", r / b);
    	r %= b;
	}
	return 0;
}
posted @ 2025-04-07 21:07  Jason227  阅读(89)  评论(0)    收藏  举报