菜鸡手搓的一个C++高精度库
菜鸡没事闲的搓了一个方便开发使用的高精度库
如有错误,大佬可指正一下
大概功能注释基本写清楚了
里面把常用运算符都重载了,深拷贝也实现了
所以直接当成正常的整型方法使用就可以了,基本差不多
支持5+a*b-c/d%5等等复杂表达式
代码
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
class BigInteger {
using Type = unsigned short;
using size_type = size_t;
using Long = long long;
using Container = std::vector<Type>; //先用官方的测试,后面换成自己的
using String = std::string; //先用官方的测试,后面换成自己的
friend std::ostream& operator<<(std::ostream& cout, BigInteger num);
friend std::istream& operator>>(std::istream& cin, BigInteger& num);
friend BigInteger operator+(const String& left, const BigInteger& num);
friend BigInteger operator+(const Long& left, const BigInteger& num);
friend BigInteger operator-(const String& left, const BigInteger& num);
friend BigInteger operator-(const Long& left, const BigInteger& num);
friend BigInteger operator*(const String& left, const BigInteger& num);
friend BigInteger operator*(const Long& left, const BigInteger& num);
friend BigInteger operator/(const String& left, const BigInteger& num);
friend BigInteger operator/(const Long& left, const BigInteger& num);
friend BigInteger operator%(const String& left, const BigInteger& num);
friend BigInteger operator%(const Long& left, const BigInteger& num);
private:
Container values; //存大整数的值,存储方式倒序存储(例:"25134",存储成:"43152")
bool sign; //存大整数的符号(0:正数,1:负数)
bool isFuck(const String& str);
//判断A >= B,满足A >= 0,B >= 0;
bool cmp(const Container& A, const Container& B);
//C = A + B, 满足A >= 0, B >= 0
Container add(const Container& A, const Container& B);
// C = A - B, 满足A >= B, A >= 0, B >= 0
Container sub(const Container& A, const Container& B);
// C = A * B, 满足A >= 0, B >= 0
Container mul(const Container& A, const Container& B);
// C = A / B, r = A % B 满足A >= 0, B >= 0
Container div(const Container& A, const Container& B, Container& r);
public:
BigInteger(); //不赋值默认是0
~BigInteger();
BigInteger(const BigInteger& num); //拷贝构造
BigInteger(const String& str); //字符串构造
BigInteger(const char* str); //字符数组构造
BigInteger(const Long& num); //对于数字的构造
String to_string(); //转成字符串的形式
Long to_num() {
return stoll(to_string()); //转成Long类型
}
size_type length(); //大整数的长度
size_type size(); //大整数的长度
Type operator[](const size_type& index); //取下标
BigInteger operator=(const BigInteger& num); //拷贝赋值
BigInteger operator=(const String& str); //字符串赋值
BigInteger operator=(const char* str); //字符数组赋值
BigInteger operator=(const Long& num); //对于数字的赋值
/********************
* 判断 *
********************/
bool operator>(const BigInteger& num); //大于
bool operator>(const Long& num); //对数字的大于
bool operator>=(const BigInteger& num); //大于等于
bool operator>=(const Long& num); //对数字的大于等于
bool operator<(const BigInteger& num); //小于
bool operator<(const Long& num); //对数字的小于
bool operator<=(const BigInteger& num); //小于等于
bool operator<=(const Long& num); //对数字的小于等于
bool operator==(const BigInteger& num); //等于
bool operator==(const Long& num); //对数字的等于
/********************
* 运算 *
********************/
//注释的就是还没写的
BigInteger operator+(const BigInteger& num); //加法
BigInteger operator+(const Long& num); //对数字的加法
BigInteger operator-(); //取负数
BigInteger operator-(const BigInteger& num); //减法
BigInteger operator-(const Long& num); //对数字的减法
BigInteger operator*(const BigInteger& num); //乘法
BigInteger operator*(const Long& num); //对数字的乘法
BigInteger operator/(const BigInteger& num); //除法
BigInteger operator/(const Long& num); //对数字的除法
BigInteger operator%(const BigInteger& num); //取模
BigInteger operator%(const Long& num); //对数字的取模
BigInteger operator+=(const BigInteger& num); //加法
BigInteger operator+=(const Long& num); //对数字的加法
BigInteger operator-=(const BigInteger& num); //减法
BigInteger operator-=(const Long& num); //对数字的减法
BigInteger operator*=(const BigInteger& num); //乘法
BigInteger operator*=(const Long& num); //对数字的乘法
BigInteger operator/=(const BigInteger& num); //除法
BigInteger operator/=(const Long& num); //对数字的除法
BigInteger operator%=(const BigInteger& num); //取模
BigInteger operator%=(const Long& num); //对数字的取模
BigInteger operator++(); //前自增
BigInteger operator++(int); //后自增
BigInteger operator--(); //前自减
BigInteger operator--(int); //后自减
};
BigInteger BigInteger::operator+=(const BigInteger& num) {
*this = operator+(num);
return *this;
}
BigInteger BigInteger::operator-=(const BigInteger& num) {
*this = operator-(num);
return *this;
}
BigInteger BigInteger::operator*=(const BigInteger& num) {
*this = operator*(num);
return *this;
}
BigInteger BigInteger::operator/=(const BigInteger& num) {
*this = operator/(num);
return *this;
}
BigInteger BigInteger::operator%=(const BigInteger& num) {
*this = operator%(num);
return *this;
}
//A%B
BigInteger BigInteger::operator%(const BigInteger& num) {
BigInteger ans;
ans.sign = sign;
div(values, num.values, ans.values);
return ans;
}
//A/B
BigInteger BigInteger::operator/(const BigInteger& num) {
BigInteger ans;
BigInteger mod_ans;
//同号为正,异号为负
ans.sign = sign != num.sign;
ans.values = div(values, num.values, mod_ans.values);
return ans;
}
//A*B
BigInteger BigInteger::operator*(const BigInteger& num) {
BigInteger ans;
//同号为正,异号为负
ans.sign = sign != num.sign;
ans.values = mul(values, num.values);
return ans;
}
//-A
BigInteger BigInteger::operator-() {
return BigInteger("0") - (*this);
}
//A-B
BigInteger BigInteger::operator-(const BigInteger& num) {
BigInteger temp = num;
temp.sign = !temp.sign;
return operator+(temp);
}
//A+B
BigInteger BigInteger::operator+(const BigInteger& num) {
BigInteger ans;
if (sign == 0 && num.sign == 0)
//A+B
ans.values = add(values, num.values);
else if (sign == 1 && num.sign == 1) {
//-A-B
ans.values = add(values, num.values);
ans.sign = 1;
}
else if (sign == 0 && num.sign == 1) {
//A-B
if (cmp(values, num.values)) {
//A >= B
ans.values = sub(values, num.values);
ans.sign = 0;
}
else {
//A < B
ans.values = sub(num.values, values);
ans.sign = 1;
}
}
else {
//B-A
if (cmp(values, num.values)) {
//B < A
ans.values = sub(values, num.values);
ans.sign = 1;
}
else {
//A <= B
ans.values = sub(num.values, values);
ans.sign = 0;
}
}
return ans;
}
bool BigInteger::operator>=(const BigInteger& num) {
return !operator<(num);
}
bool BigInteger::operator<(const BigInteger& num) {
return operator<=(num) && !operator==(num);
}
bool BigInteger::operator<=(const BigInteger& num) {
return !operator>(num);
}
bool BigInteger::operator>(const BigInteger& num) {
//正数比负数大
if (sign != num.sign)
return sign < num.sign;
//如果符号相同,并且都是正数,并且前者长度大那么他就大,负数相反
if (values.size() > num.values.size())
return sign == 0;
//到这里应该符号相同,并且长度都相同了,直接从最后一个往前比就可以
size_type len = values.size();
for (size_type i = len - 1; i >= 0; i--) {
if (values[i] != num.values[i])
return sign ? values[i] < num.values[i] : values[i] > num.values[i];
if (i == 0)
break;
}
return false;
}
bool BigInteger::operator==(const BigInteger& num) {
if (sign != num.sign || values.size() != num.values.size())
return false;
size_type len = size();
for (size_type i = 0; i < len; i++)
if (values[i] != num.values[i])
return false;
return true;
}
BigInteger::Type BigInteger::operator[](const size_type& index) {
size_type len = length();
if (index < 0 || index >= len)
throw "OVERFLOW!!!!!";
return values[len - index - 1];
}
BigInteger::size_type BigInteger::length() {
return values.size();
}
BigInteger::size_type BigInteger::size() {
return values.size();
}
BigInteger BigInteger::operator=(const Long& num) {
values.clear();
Long temp = num;
sign = temp < 0;
temp = abs(temp);
while (temp) {
values.push_back(temp % 10);
temp /= 10;
}
return *this;
}
BigInteger BigInteger::operator=(const BigInteger& num) {
values = num.values;
sign = num.sign;
return *this;
}
BigInteger BigInteger::operator=(const String& str) {
values.clear();
if (isFuck(str)) {
//如果用户输入的值是乱的我就做这个判断
values.push_back(0);
sign = 0;
}
else {
//如果不乱就走这个
sign = str[0] == '-'; //取符号位
size_type len = str.length();
//通过index找到正确的位置
size_type index = 0;
for (size_type i = 0; i < len; i++) {
if (str[i] != '0' && str[i] != '+' && str[i] != '-')
break;
else
index++;
}
//倒序存值
for (size_type i = len - 1; i >= index; i--) {
values.push_back(str[i] - '0');
if (i == index)
break;
}
}
return *this;
}
BigInteger BigInteger::operator=(const char* str) {
return operator=(String(str));
}
BigInteger::BigInteger(const char* str) :BigInteger{ String{str} } {}
BigInteger::BigInteger(const String& str) {
operator=(str);
}
BigInteger::BigInteger(const Long& num) {
operator=(num);
}
BigInteger::String BigInteger::to_string() {
String str;
if (sign && !(values.size() == 1 && values[0] == 0))
str.push_back('-');
for (auto it = values.rbegin(); it != values.rend(); ++it)
str.push_back(*it + '0');
return str;
}
BigInteger::BigInteger() {
values.push_back(0);
sign = 0;
}
BigInteger::~BigInteger() {
}
BigInteger::BigInteger(const BigInteger& num) {
sign = num.sign;
values = num.values;
}
BigInteger BigInteger::operator+=(const Long& num) {
return operator+=(BigInteger(num));
}
BigInteger BigInteger::operator-=(const Long& num) {
return operator-=(BigInteger(num));
}
BigInteger BigInteger::operator*=(const Long& num) {
return operator*=(BigInteger(num));
}
BigInteger BigInteger::operator/=(const Long& num) {
return operator/=(BigInteger(num));
}
BigInteger BigInteger::operator%=(const Long& num) {
return operator%=(BigInteger(num));
}
BigInteger BigInteger::operator++() {
*this = *this + 1;
return *this;
}
BigInteger BigInteger::operator++(int) {
BigInteger temp = *this;
++(*this);
return temp;
}
BigInteger BigInteger::operator--() {
*this = *this - 1;
return *this;
}
BigInteger BigInteger::operator--(int) {
BigInteger temp = *this;
--(*this);
return temp;
}
BigInteger BigInteger::operator-(const Long& num) {
return operator-(BigInteger(num));
}
BigInteger BigInteger::operator+(const Long& num) {
return operator+(BigInteger(num));
}
BigInteger BigInteger::operator*(const Long& num) {
return operator*(BigInteger(num));
}
BigInteger BigInteger::operator/(const Long& num) {
return operator/(BigInteger(num));
}
BigInteger BigInteger::operator%(const Long& num) {
return operator%(BigInteger(num));
}
bool BigInteger::operator>(const Long& num) {
return operator>(BigInteger(num));
}
bool BigInteger::operator<(const Long& num) {
return operator<(BigInteger(num));
}
bool BigInteger::operator>=(const Long& num) {
return operator>=(BigInteger(num));
}
bool BigInteger::operator<=(const Long& num) {
return operator<=(BigInteger(num));
}
bool BigInteger::operator==(const Long& num) {
return operator==(BigInteger(num));
}
bool BigInteger::isFuck(const String& str) {
if (str.empty())
return true;
size_type len = str.length();
for (size_type i = str[0] == '-' || str[0] == '+'; i < len; i++)
if (str[i] < '0' || str[i] > '9')
return true;
return false;
}
bool BigInteger::cmp(const Container& A, const Container& B) {
if (A.size() != B.size()) return A.size() > B.size();
size_type A_size = A.size();
for (size_type i = A_size - 1; i >= 0; i--) {
if (A[i] != B[i])
return A[i] > B[i];
if (i == 0)
break;
}
return true;
}
BigInteger::Container BigInteger::add(const Container& A, const Container& B) {
if (A.size() < B.size()) return add(B, A);
Container C;
size_type t = 0;
for (size_type i = 0; i < A.size(); i++) {
t += A[i];
if (i < B.size())
t += B[i];
C.push_back(t % 10);
t /= 10;
}
if (t)
C.push_back(t);
return C;
}
BigInteger::Container BigInteger::sub(const Container& A, const Container& B) {
Container C;
for (int i = 0, t = 0; i < A.size(); i++) {
t = A[i] - t;
if (i < B.size())
t -= B[i];
C.push_back((t + 10) % 10);
t = t < 0;
}
while (C.size() > 1 && C.back() == 0)
C.pop_back();
return C;
}
BigInteger::Container BigInteger::mul(const Container& A, const Container& B) {
Container C(A.size() + B.size(), 0); // 初始化为 0
size_type A_len = A.size();
size_type B_len = B.size();
for (size_type i = 0; i < A_len; i++)
for (size_type j = 0; j < B_len; j++)
C[i + j] += A[i] * B[j];
size_type C_len = C.size();
size_type t = 0;
for (size_type i = 0; i < C_len; i++) {
t += C[i];
C[i] = t % 10;
t /= 10;
}
while (C.size() > 1 && C.back() == 0)
C.pop_back();
return C;
}
BigInteger::Container BigInteger::div(const Container& A, const Container& B, Container& r) {
Container C;
if (!cmp(A, B)) {
C.push_back(0);
r.assign(A.begin(), A.end());
return C;
}
size_type j = B.size();
r.assign(A.end() - j, A.end());
while (j <= A.size()) {
size_type k = 0;
while (cmp(r, B)) {
Container s = sub(r, B);
r.clear();
r.assign(s.begin(), s.end());
k++;
}
C.push_back(k);
if (j < A.size())
r.insert(r.begin(), A[A.size() - j - 1]);
if (r.size() > 1 && r.back() == 0)
r.pop_back();
j++;
}
reverse(C.begin(), C.end());
while (C.size() > 1 && C.back() == 0)
C.pop_back();
return C;
}
std::ostream& operator<<(std::ostream& cout, BigInteger num) {
std::cout << num.to_string();
return cout;
}
std::istream& operator>>(std::istream& cin, BigInteger& num) {
BigInteger::String str;
std::cin >> str;
num.operator=(str);
return cin;
}
BigInteger operator+(const BigInteger::String& left, const BigInteger& num) {
return BigInteger(left).operator+(num);
}
BigInteger operator+(const BigInteger::Long& left, const BigInteger& num) {
return BigInteger(left).operator+(num);
}
BigInteger operator-(const BigInteger::String& left, const BigInteger& num) {
return BigInteger(left).operator-(num);
}
BigInteger operator-(const BigInteger::Long& left, const BigInteger& num) {
return BigInteger(left).operator-(num);
}
BigInteger operator*(const BigInteger::String& left, const BigInteger& num) {
return BigInteger(left).operator*(num);
}
BigInteger operator*(const BigInteger::Long& left, const BigInteger& num) {
return BigInteger(left).operator*(num);
}
BigInteger operator/(const BigInteger::String& left, const BigInteger& num) {
return BigInteger(left).operator/(num);
}
BigInteger operator/(const BigInteger::Long& left, const BigInteger& num) {
return BigInteger(left).operator/(num);
}
BigInteger operator%(const BigInteger::String& left, const BigInteger& num) {
return BigInteger(left).operator%(num);
}
BigInteger operator%(const BigInteger::Long& left, const BigInteger& num) {
return BigInteger(left).operator%(num);
}
int main() {
BigInteger a, b;
cin >> a >> b;
cout << a + b << endl;
return 0;
}