纪录一下自己做的C++高精度算法加减乘除

本文介绍了一个名为BigDecimal的自定义类,用于处理大数运算,包括加法、减法、乘法和除法。文章指出类存在负数运算问题以及除数为零的逻辑错误,并提到了使用逐位试商法实现除法。
摘要由CSDN通过智能技术生成

注意!这个类无法进行负数的运算。还有就是在除数中使用的是逐数试商的算法。

而且乘法的逻辑好像有问题,,总的来说这个类不够完美,但是毕竟是我自己手搓的,对我还是很有意义的

#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;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值