高精度整数类
写高精度的时候顺便写的,还有一些功能未实现,现在只能进行非负整数之间的运算,但是结果可以是负数
加减乘除均支持高精度整数
代码如下
Utilities类是我写代码过程中创建的一个类,此处删去了不必要的功能
#include<vector>
#include<memory>
#include<string>
using std::vector;
using std::string;
using std::unique_ptr;
using std::shared_ptr;
using std::make_shared;
class Utilities
{
public:
//判断该字符串是否为数字
static bool IsNumber(const string& s)
{
return (s.find_first_not_of("-0123456789") == string::npos);
}
};
/*High precision integer*/
//TODO:使高精度整数能够拥有负整数参数
#include<memory>
#include<vector>
#include <string>
#include <sstream>
#include <algorithm>
#include"Utilities.h"
using std::vector;
using std::string;
using std::shared_ptr;
using std::pair;
using std::make_shared;
//高精度整数
class HighPrecisionInteger
{
public:
//默认构造函数
HighPrecisionInteger()
{
data = new vector<unsigned short>;
data->clear();
minus = false;
}
//vector to HighPrecisionInteger
HighPrecisionInteger(const vector<unsigned short>& _vector)
{
data = new vector<unsigned short>(_vector);
minus = false;
}
//拷贝构造函数
HighPrecisionInteger(const HighPrecisionInteger& _instance)
{
data = new vector<unsigned short>(*_instance.data);
minus = _instance.minus;
}
//拷贝构造函数
HighPrecisionInteger(HighPrecisionInteger&& _instance)
{
data = new vector<unsigned short>;
data->swap(*_instance.data);
minus = _instance.minus;
}
//int64 to HighPrecisionInteger
HighPrecisionInteger(int64_t _number)
{
data = new vector<unsigned short>;
this->minus = false;
if (_number < 0)
{
minus = true;
_number = -_number;
}
do
{
data->push_back(_number % 10);
_number /= 10;
} while (_number);
}
//string to HighPrecisionInteger
HighPrecisionInteger(const string& s)
{
data = new vector<unsigned short>;
minus = false;
if (!Utilities::IsNumber(s))
return;
int len = s.size();
for (int i = len - 1; i >= 0; i--)
{
if (i != 0 || s[i] != '-')
data->push_back(s[i] - '0');
}
if (s[0] == '-')minus = true;
}
~HighPrecisionInteger()
{
delete data;
data = nullptr;
}
public:
//将大整数转化为字符数组
char* ToString()
{
if (this->data->empty())return nullptr;
shared_ptr<char*> s = make_shared<char*>(new char[data->size() + 10]);
for (int i = data->size() - 1; i >= 0; i--)
{
(*s)[data->size() - i] = char(data->at(i) + '0');
}
(*s)[data->size() + 1] = '\0';
//判断是否为负数
if (minus == true)
{
(*s)[0] = '-';
return *make_shared<char*>(*s);
}
return *make_shared<char*>(*s + 1);
}
//返回大整数位数
int Size()
{
return data->size();
}
//清空
void Clear()
{
data->clear();
minus = false;
}
public:
HighPrecisionInteger& operator + (const HighPrecisionInteger&);
void operator += (const HighPrecisionInteger&);
HighPrecisionInteger& operator - (const HighPrecisionInteger&);
void operator -= (const HighPrecisionInteger&);
HighPrecisionInteger& operator * (const HighPrecisionInteger&);
void operator *= (const HighPrecisionInteger&);
//除法运算,返回商与余数,第一个参数为商,第二个参数为余数
pair<HighPrecisionInteger, HighPrecisionInteger>& operator / (const HighPrecisionInteger&);
void operator /= (const HighPrecisionInteger&);
HighPrecisionInteger& operator = (const HighPrecisionInteger&);
const bool operator < (const HighPrecisionInteger&);
const bool operator <= (const HighPrecisionInteger&);
const bool operator > (const HighPrecisionInteger&);
const bool operator >= (const HighPrecisionInteger&);
const bool operator == (const HighPrecisionInteger&);
const bool operator != (const HighPrecisionInteger&);
private:
vector<unsigned short>* data;
bool minus;
};
const bool HighPrecisionInteger::operator>=(const HighPrecisionInteger& _instance)
{
//判断符号
if (this->minus == true && _instance.minus == false)
return false;
if (this->minus == false && _instance.minus == true)
return true;
//判断位数
if (this->data->size() > _instance.data->size())
{
if (this->minus == true)return false;
else return true;
}
if (this->data->size() < _instance.data->size())
{
if (this->minus == false)return false;
else return true;
}
//判断每一位
for (int i = this->data->size() - 1; i >= 0; i--)
{
if (this->data->at(i) != _instance.data->at(i))
{
if (this->data->at(i) < _instance.data->at(i))
{
if (this->minus == true)return true;
else return false;
}
else
{
if (this->minus == false)return true;
else return false;
}
}
}
}
const bool HighPrecisionInteger::operator<(const HighPrecisionInteger& _instance)
{
return !(*this >= _instance);
}
const bool HighPrecisionInteger::operator<=(const HighPrecisionInteger& _instance)
{
return (*this < _instance || *this == _instance);
}
const bool HighPrecisionInteger::operator>(const HighPrecisionInteger& _instance)
{
return !(*this <= _instance);
}
const bool HighPrecisionInteger::operator==(const HighPrecisionInteger& _instance)
{
return ((this->minus == _instance.minus) && (this->data == _instance.data));
}
const bool HighPrecisionInteger::operator!=(const HighPrecisionInteger& _instance)
{
return !(*this == _instance);
}
HighPrecisionInteger& HighPrecisionInteger::operator= (const HighPrecisionInteger& _instance)
{
this->data->assign(_instance.data->begin(), _instance.data->end());
this->minus = _instance.minus;
return *this;
}
void HighPrecisionInteger::operator+=(const HighPrecisionInteger& _instance)
{
//进位
int carry = 0;
//加法运算当前位数
int ptr = 0;
//两个数字的长度
int len1 = this->data->size() - 1;
int len2 = _instance.data->size() - 1;
while (ptr <= len1 || ptr <= len2)
{
//用来存储两个数字第i位相加之和
int temp;
//超过了第一个数字的位数则第i位答案为第二个数字的第i位加上进位
if (ptr > len1)
{
temp = _instance.data->at(ptr) + carry;
carry = temp / 10;
this->data->push_back(temp % 10);
}
else
if (ptr > len2)
{
temp = this->data->at(ptr) + carry;
this->data->at(ptr) = temp % 10;
carry = temp / 10;
}
else
{
temp = this->data->at(ptr) + _instance.data->at(ptr) + carry;
this->data->at(ptr) = temp % 10;
carry = temp / 10;
}
ptr++;
}
//最后一位进位判断
if (carry != 0)
{
this->data->push_back(carry);
carry = 0;
}
}
HighPrecisionInteger& HighPrecisionInteger::operator+(const HighPrecisionInteger& _instance)
{
static HighPrecisionInteger* ptr = nullptr;
delete ptr;
ptr = new HighPrecisionInteger(*this);
*ptr += _instance;
return *ptr;
}
HighPrecisionInteger& HighPrecisionInteger::operator-(const HighPrecisionInteger& _instance)
{
static HighPrecisionInteger* ans = nullptr;
delete ans;
ans = new HighPrecisionInteger();
//进位
int carry = 0;
//运算到的位数
int ptr = 0;
//是否调换减数与被减数之间的位置
bool isReversed = false;
//判断是否调换减数与被减数
if (this->data->size() - 1 < _instance.data->size() - 1)isReversed = true;
else if (this->data->size() - 1 == _instance.data->size() - 1)
{
//从后往前判断谁更大
for (int i = this->data->size() - 1; i >= 0; i--)
{
if (this->data->at(i) != _instance.data->at(i))
{
isReversed = this->data->at(i) < _instance.data->at(i);
break;
}
}
}
//规定减法位n1-n2
const HighPrecisionInteger* n1, * n2;
if (isReversed)
{
n1 = &_instance;
n2 = this;
}
else
{
n1 = this;
n2 = &_instance;
}
while (ptr <= n1->data->size() - 1)
{
//用来存储两个数字第i位相加之和
int temp;
if (ptr > n2->data->size() - 1)
{
temp = n1->data->at(ptr) + carry;
carry = 0;
if (temp < 0)
{
temp += 10;
carry = -1;
}
ans->data->push_back(temp % 10);
}
else
{
temp = n1->data->at(ptr) - n2->data->at(ptr) + carry;
carry = 0;
if (temp < 0)
{
temp += 10;
carry = -1;
}
ans->data->push_back(temp % 10);
}
ptr++;
}
//数字0判断
while (!ans->data->empty() && ans->data->at(ans->data->size() - 1) == 0)
ans->data->pop_back();
if (isReversed == true)ans->minus = true;
if (ans->data->empty())
{
ans->data->push_back(0);
ans->minus = false;
}
return *ans;
}
void HighPrecisionInteger::operator-=(const HighPrecisionInteger& _instance)
{
*this = *this - _instance;
}
HighPrecisionInteger& HighPrecisionInteger::operator*(const HighPrecisionInteger& _instance)
{
static HighPrecisionInteger* ans = nullptr;
delete ans;
ans = new HighPrecisionInteger();
//判断乘以0的情况
if (this->data->at(this->data->size() - 1) == 0
|| _instance.data->at(_instance.data->size() - 1) == 0)
{
*ans = HighPrecisionInteger(0);
return *ans;
}
//进位
int carry = 0;
//指针
const HighPrecisionInteger* multiplicator = nullptr; //乘数
const HighPrecisionInteger* multiplicand = nullptr; //被乘数
//长度更长的为被乘数
if (this->data->size() > _instance.data->size())
{
multiplicand = this;
multiplicator = &_instance;
}
else
{
multiplicand = &_instance;
multiplicator = this;
}
HighPrecisionInteger temp;
//枚举数字
//乘数
for (int i = 0, limi = multiplicator->data->size() - 1; i <= limi; i++)
{
temp.Clear();
carry = 0;
//末尾插入0
for (int k = 0; k < i; k++)
temp.data->push_back(0);
//被乘数
for (int j = 0, limj = multiplicand->data->size() - 1; j <= limj; j++)
{
//储存两个数的乘积
int _ans = 0;
_ans = multiplicator->data->at(i) * multiplicand->data->at(j) + carry;
carry = _ans / 10;
temp.data->push_back(_ans % 10);
}
//判断最后进位
if (carry != 0)
{
temp.data->push_back(carry);
carry = 0;
}
*ans += temp;
}
ans->minus = (this->minus == _instance.minus) ? false : true;
return *ans;
}
void HighPrecisionInteger::operator*=(const HighPrecisionInteger& _instance)
{
(*this) = (*this) * _instance;
}
//除法运算,返回商与余数,第一个参数为商,第二个参数为余数
pair<HighPrecisionInteger, HighPrecisionInteger>& HighPrecisionInteger::operator/(const HighPrecisionInteger& _instance)
{
static pair<HighPrecisionInteger, HighPrecisionInteger>* ans = nullptr;
delete ans;
ans = new pair<HighPrecisionInteger, HighPrecisionInteger>();
//计算每一位时剩下的余数
HighPrecisionInteger remainder = 0;
//商
vector<unsigned short>quotient = {};
//从高到低枚举被除数每一位
for (int i = this->data->size() - 1; i >= 0; i--)
{
remainder = remainder * 10 + this->data->at(i);
//第i位的商
quotient.push_back(0);
while (remainder >= _instance)
{
remainder -= _instance;
quotient[quotient.size() - 1]++;
}
}
//将商转换为高精度整数的存储形式并去掉末尾0
if (!quotient.empty())
std::reverse(quotient.begin(), quotient.end());
while (!quotient.empty() && quotient[quotient.size() - 1] == 0)
quotient.pop_back();
if (quotient.empty())
quotient.push_back(0);
//写入数据
*(ans->first.data) = quotient;
ans->second = remainder;
return *ans;
}
void HighPrecisionInteger::operator/=(const HighPrecisionInteger& _instance)
{
*this = (*this / _instance).first;
}