高精度运算:大数计算全攻略
大家好,今天小编给大家带来的是关于高精度问题的解决办法!
一、什么是高精度问题?
1.定义:
你想问的可能是 “高精度是什么问题”。高精度问题通常是指需要处理超出计算机标准数据类型所能表示范围的数值计算相关的问题 。
由于计算机中的整数类型、浮点类型都有固定的位数和范围限制,比如常见编程语言中的int
、long
、float
、double
等数据类型可表达数值范围都有限,当面临大数运算,标准数据类型就无法胜任,此时就产生了高精度计算问题 。
解决高精度问题,一般会采用特定的数据结构来表示这些大数字,例如用字符串或者数组存储大数字,之后再通过模拟人类手工计算的方式,像竖式加法、乘法竖式等逻辑来实现高精度数的加、减、乘、除等数值运算 。
2.注意点:
2.1.要大概了解数据类型的范围,这样才可以判断是否是高精度问题!
2.2.我们需要使用什么方法去存这个大数。eg.数组\字符串等
2.3.如何去模拟计算过程
3.哪些语言存在高精度问题
C/C++/Java存在高精度问题,对于python来说不存在高精度问题
二、高精度加法(大数+大数)
1.用什么存?
我们这里采用vector进行存储(也可以使用数组进行存储)。什么是vector?vector
是 C++ 标准库(STL)中的容器,用于动态管理数组(即可变长度的数组)。
大家注意c语言中没有原生的vector哈!!!
2.如何去模拟计算过程?
我们可以想一下我们平时做加法的时候,是不是先从个位加起来(这里就涉及到了一个存储,逆序存储数据个位在前),如果超过了10就会进行进位,以此内推!
图示:
3.代码演示
#include<iostream>
#include<vector>using namespace std;/*** 高精度加法函数* @param A 存储第一个加数的vector(逆序存储,低位在前)* @param B 存储第二个加数的vector(逆序存储,低位在前)* @return 存储和的vector(逆序存储,低位在前)*/
vector<int> add(vector<int>& A, vector<int>& B)
{int t = 0; // 用于存储当前位的和以及进位,初始值为0vector<int> c; // 存储加法结果的vector// 循环处理每一位,直到两个数的所有位都处理完毕// i < A.size() || i < B.size() 确保处理完所有位数for (int i = 0; i < A.size() || i < B.size(); i++){// 如果A还有未处理的位,就把该位的值加到t中if (i < A.size()) t += A[i];// 如果B还有未处理的位,就把该位的值加到t中if (i < B.size()) t += B[i];// 将当前位的结果(t对10取余)存入结果vectorc.push_back(t % 10);// 更新进位(t除以10的商,0或1)t /= 10;}// 如果所有位处理完毕后还有进位(t=1),需要将进位添加到结果中if (t) c.push_back(t);return c;
}int main()
{string a, b; // 用字符串存储输入的大整数,避免整数类型长度限制cin >> a >> b;vector<int> A, B; // 用vector存储大整数的每一位(逆序存储,方便加法运算)// 将字符串a转换为逆序的数字vector// 例如:"123" -> [3, 2, 1](个位在前,高位在后)for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); // 字符转数字:'0'的ASCII码是48,减去后得到对应的整数// 同理处理字符串bfor (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');// 调用高精度加法函数,得到结果vector(逆序)auto c = add(A, B);// 逆序输出结果vector,得到正确的数字顺序// 例如:结果vector为[0, 1, 1] -> 输出"110"for (int i = c.size() - 1; i >= 0; i--){cout << c[i];}return 0;
}
三、高精度减法(大数-大数)
1.用什么存?
跟加法一样这里采用vector进行存储(也可以使用数组进行存储)。
2.如何去模拟计算过程?
我们可以想一下我们平时做减法的时候,是不是先从个位减起走(这里就涉及到了一个存储,逆序存储数据个位在前),如果减出来的数字小于0就会进行借位,以此内推!如果是一个小的数减去一个大的数,就会产生负数,我们可以先计算出大数-小数的结果,如果是负数在前面加一个负号!
图示:
3.代码演示
#include<iostream>
#include<vector>
using namespace std;// 比较两个高精度数的大小
bool cmp(vector<int>& A, vector<int>& B)
{if (A.size() != B.size()) return A.size() > B.size();// 从高位到低位比较for (int i = A.size() - 1; i >= 0; i--){if (A[i] != B[i]) return A[i] > B[i];}return true; // 两数相等
}// 高精度减法:计算A - B(需保证A >= B)
vector<int> sub(vector<int>& A, vector<int>& B)
{vector<int> c;int t = 0; // 用于处理借位for (int i = 0; i < A.size(); i++){t = A[i] - t; // 先减去上一位的借位if (i < B.size()) t -= B[i]; // 减去B的当前位// 计算当前位结果:如果t为负则加10,否则直接取tc.push_back((t + 10) % 10);// 更新借位:如果t < 0说明有借位,否则没有if (t < 0) t = 1;else t = 0;}// 去除前导零(保留至少一位)while (c.size() > 1 && c.back() == 0) c.pop_back();return c;
}int main()
{string a, b;cin >> a >> b;vector<int> A, B;// 将字符串逆序存储为数字数组(个位在前)for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');if (cmp(A, B)){// A >= B 直接计算A - Bauto c = sub(A, B);for (int i = c.size() - 1; i >= 0; i--) printf("%d", c[i]);}else{// A < B 计算B - A并添加负号auto c = sub(B, A);printf("-");for (int i = c.size() - 1; i >= 0; i--) printf("%d", c[i]);}return 0;
}
三、总结
大家在写高精度的时候要搞明白用什么进行存储?再就是如何模拟出算数运算?
成功的秘诀就是每天都比别人多努力一点,大家共勉!一起加油!!!