注意!这个类无法进行负数的运算。还有就是在除数中使用的是逐数试商的算法。
而且乘法的逻辑好像有问题,,总的来说这个类不够完美,但是毕竟是我自己手搓的,对我还是很有意义的
#include<iostream>
#include<vector>//引入数组
#include<algorithm>
#include<utility>//引入pair
#include<stdexcept>//引入std::logic_error,逻辑报错
using namespace std;
class BigDecimal {
private:
const static int MAXSIZE = 5000;//大数的最大大小
vector<int>num;//储存大数的数组
int length;//大数的长度
bool Positive;//正负数
//初始化,委托构造函数
void init() {
num.resize(MAXSIZE, 0);
length = 0;
}
//除法真正的实现(本方法实现的是"逐位试商"法,其他除法还有牛顿-拉弗森除法、二分查找法等)
pair<BigDecimal, BigDecimal> dividesHelper(const BigDecimal& b) {
if (b == 0)
throw std::logic_error("division by zero");
BigDecimal div;//最终返回的商
BigDecimal mod;//最终返回的余数
for (int i = length - 1; i >= 0; --i) {
mod = mod * 10 + num[i];
int times = 0;
while (mod > b) {
mod -= b;
times++;
}
div.num[i] = times;
}
div.length = this->length;
while (div.length - 1 >= 0 && div.num[div.length - 1] == 0) {
div.length--;
}
return{ div,mod };
}
public:
//构造函数
BigDecimal() {
init();
};
BigDecimal(long long b) {
init();
while (b) {
num[length] = b % 10;
b /= 10;
++length;
}
};
BigDecimal(string& s) :num(s.begin(), s.end()), length(s.size()) {
for (auto& nu : num) {
nu -= '0';
}
reverse(num.begin(), num.begin() + length);
};
BigDecimal(const BigDecimal& b) :num(b.num), length(b.length) {};
BigDecimal(const BigDecimal&& b) :num(move(b.num)), length(move(b.length)) {};
//加法的实现:
BigDecimal operator+(const BigDecimal& b) const {
BigDecimal res;
int& res_length = res.length;
int carry = 0;//carry是进位
for (int i = 0; i < this->length || i < b.length; ++i) {
int tem = this->num[i] + b.num[i] + carry;
res.num[res_length++] = tem % 10;
carry = tem / 10;
}
if (carry != 0) {
res.num[res_length++] = carry;
}
return res;
}
//减法的实现
BigDecimal operator-(const BigDecimal& b) const {
if (*this < b)
throw std::logic_error("没法做负数的减法");
BigDecimal res(*this);
res.length = 0;
for (int i = 0; i < this->length || i < b.length; ++i) {
if (res.num[i] < b.num[i]) {
res.num[i + 1]--;
res.num[i] += 10;
}
res.num[res.length++] = res.num[i] - b.num[i];
}
//去除最高位的0
while (res.length - 1 >= 1 && res.num[res.length - 1] == 0) {
res.length--;
}
return res;
}
//乘法的实现
BigDecimal operator*(const BigDecimal& b)const {
BigDecimal res;
for (int i = 0; i < this->length; ++i) {
int carry = 0;//进位
int multi = this->num[i];//要乘的个位数 为 num[i]
BigDecimal needToPlus;//计算数b与num[i]相乘的结果
int& needToPlus_length = needToPlus.length;
needToPlus_length += i;//使数b乘以10的i次方
for (int j = 0; j < b.length; ++j) {
int tem = b.num[j] * multi + carry;
needToPlus.num[needToPlus_length++] = tem % 10;
carry = tem / 10;
}
while (carry) {//和加法不同,有可能会进很多位
needToPlus.num[needToPlus_length++] = carry % 10;
carry /= 10;
}
res += needToPlus;//将最终计算结果与每一次大数与个位数相乘的结果相加
}
while (res.length - 1 >= 1 && res.num[res.length - 1] == 0) {
res.length--;
}
return res;
}
//除法的实现
BigDecimal operator/(const BigDecimal& b) {
if (*this < b) {
return BigDecimal();
}
return dividesHelper(b).first;
}
//取余的实现
BigDecimal operator%(const BigDecimal& b) {
if (length < b.length) {
return *this;
}
return dividesHelper(b).second;
}
//<<运算符重载
friend ostream& operator<<(ostream& os, const BigDecimal& BigD) {
if (BigD.length == 0)//TODO
os << BigD.num[0];
for (int i = BigD.length - 1; i >= 0; --i) {
os << BigD.num[i];
}
return os;
}
//>>运算符重载
friend istream& operator>>(istream& is, BigDecimal& BigD) {
string s;
is >> s;
for (char& ch : s)
ch -= '0';
copy(s.rbegin(), s.rend(), BigD.num.begin());
BigD.length = s.length();
return is;
}
//赋值操作运算符重载
BigDecimal& operator+=(const BigDecimal& b) {
*this = *this + b;
return *this;
}
BigDecimal& operator-=(const BigDecimal& b) {
*this = *this - b;
return *this;
}
BigDecimal& operator*=(const BigDecimal& b) {
*this = *this * b;
return *this;
}
BigDecimal& operator/=(const BigDecimal& b) {
*this = this->dividesHelper(b).first;
return *this;
}
BigDecimal& operator%=(const BigDecimal& b) {
*this = this->dividesHelper(b).second;
return *this;
}
BigDecimal& operator=(const BigDecimal& b) {
this->num = b.num;
this->length = b.length;
return *this;
}
//比较操作符重载
bool operator==(const BigDecimal& b) const {
if (length > b.length || length < b.length) {
return false;
}
for (int i = length - 1; i >= 0; --i) {
if (num[i] != b.num[i]) {
return false;
}
}
return true;
}
bool operator>(const BigDecimal& b) const {
if (length > b.length) {
return true;
}
if (length < b.length) {
return false;
}
for (int i = length - 1; i >= 0; --i) {
if (num[i] > b.num[i]) {
return true;
}
else if (num[i] < b.num[i]) {
return false;
}
}
return false;
}
bool operator<(const BigDecimal& b) const {
if (length < b.length) {
return true;
}
if (length > b.length) {
return false;
}
for (int i = length - 1; i >= 0; --i) {
if (num[i] < b.num[i]) {
return true;
}
else if (num[i] > b.num[i]) {
return false;
}
}
return false;
}
bool operator>=(const BigDecimal& b)const {
if (length > b.length) {
return true;
}
if (length < b.length) {
return false;
}
for (int i = length - 1; i >= 0; --i) {
if (num[i] > b.num[i]) {
return true;
}
else if (num[i] < b.num[i]) {
return false;
}
}
return true;
}
bool operator<=(const BigDecimal& b)const {
if (length < b.length) {
return true;
}
if (length > b.length) {
return false;
}
for (int i = length - 1; i >= 0; --i) {
if (num[i] < b.num[i]) {
return true;
}
else if (num[i] > b.num[i]) {
return false;
}
}
return true;
}
};
void Solution() {
BigDecimal a,b;
cin >> a >> b;
cout << a * b;
}
int main() {
Solution();
return 0;
}