C++大整数类BigInteger的四则运算

前言

众所周知,C++莫得高精度,本蒟蒻在网上找到的代码也没有特别成系统的,所以决定自己写个库开心一下~~~

头文件:BigInteger.h
#pragma once
#include <iostream>
#include <istream>
#include <ostream>
#include <algorithm>
#include <vector>
using namespace std;

class BigInteger
{
	private:
		static const int BASE = 10000;
		static const int WIDTH = 4;
		vector <int> s;
	public:
		BigInteger(long long num = 0) { *this = num; };
		friend ostream& operator << (ostream& out, const BigInteger& x);
		friend istream& operator >> (istream& in, const BigInteger& x);
		bool operator < (const BigInteger& b) const;
		bool operator > (const BigInteger& b) const;
		bool operator <= (const BigInteger& b) const;
		bool operator >= (const BigInteger& b) const;
		bool operator != (const BigInteger& b) const;
		bool operator == (const BigInteger& b) const;
		BigInteger operator = (long long num);
		BigInteger operator = (const string& str);
		BigInteger operator + (const BigInteger& b) const;
		BigInteger operator - (const BigInteger& b) const;
		BigInteger operator * (const BigInteger& b) const;
		BigInteger operator / (const BigInteger& b) const;
		BigInteger operator % (const BigInteger& b) const;
		BigInteger operator += (const BigInteger& b);
		BigInteger operator -= (const BigInteger& b);
		BigInteger operator *= (const BigInteger& b);
		BigInteger operator /= (const BigInteger& b);
		BigInteger operator %= (const BigInteger& b);
		BigInteger fast_pow(BigInteger x, BigInteger y);
};
源文件:BigInteger.cpp
#include <vector>
#include <istream>
#include <ostream>
#include <algorithm>
#include <cmath>
#include "BigInteger.h"
using namespace std;

ostream& operator << (ostream& out, const BigInteger& x)
{
	out << x.s.back();
	for (int i = x.s.size() - 2; i >= 0; --i)
	{
		char buf[20];
		sprintf_s(buf, "%04d", x.s[i]);
		for (int j = 0; j < strlen(buf); ++j)
			out << buf[j];
	}
	return out;
}

istream& operator >> (istream& in, BigInteger& x)
{
	string s;
	if (!(in >> s))  return in;
	x = s;
	return in;	
}

bool BigInteger::operator < (const BigInteger& b) const
{
	if (s.size() != b.s.size())  return s.size() < b.s.size();
	for (int i = s.size() - 1; i >= 0; --i)
		if (s[i] != b.s[i])  return s[i] < b.s[i];
	return false;
}

bool BigInteger::operator > (const BigInteger& b) const
{
	return b < *this;
}

bool BigInteger::operator <= (const BigInteger& b) const
{
	return !(b < *this);
}

bool BigInteger::operator >= (const BigInteger& b) const
{
	return !(*this < b);
}

bool BigInteger::operator != (const BigInteger& b) const
{
	return b < *this || *this < b;
}

bool BigInteger::operator == (const BigInteger& b) const
{
	return !(b < *this) && !(*this < b);
}

BigInteger BigInteger::operator = (long long num)
{
	s.clear();
	do
	{
		s.push_back(num % BASE);
		num /= BASE;
	} while (num > 0);
	return *this;
}

BigInteger BigInteger::operator = (const string& str)
{
	s.clear();
	int x, len = (str.length() - 1) / WIDTH + 1;
	for (int i = 0; i < len; ++i)
	{
		int end = str.length() - i * WIDTH;
		int start = max(0, end - WIDTH);
		sscanf_s(str.substr(start, end - start).c_str(), "%d", &x);
		s.push_back(x);
	}
	return *this;
}

BigInteger BigInteger::operator + (const BigInteger& b) const
{
	BigInteger c;
	c.s.clear();
	for (int i = 0, g = 0; ; ++i)
	{
		if (g == 0 && i >= s.size() && i >= b.s.size())  break;
		int x = g;
		if (i < s.size())  x += s[i];
		if (i < b.s.size())	x += b.s[i];
		c.s.push_back(x % BASE);
		g = x / BASE;
	}
	return c;
}

BigInteger BigInteger::operator - (const BigInteger& b) const
{
	BigInteger c;
	c.s.clear();
	int MAX = max(s.size(), b.s.size());
	if (*this > b)
	{
		for (int i = 0, g = 0; ; ++i)
		{
			bool borrow = 0;
			if (g == 0 && i >= MAX)  break;
			int x = g;
			if (i < s.size())  x += s[i];
			if (i < b.s.size())  x -= b.s[i];
			if (x < 0)  borrow = 1;
			c.s.push_back((x + BASE) % BASE);
			g = x / BASE;
			if (borrow)  --g;
		}
		return c;
	}
	else if (*this == b)
	{
		return c;
	}
	else
	{
		for (int i = 0, g = 0; ; ++i)
		{
			bool borrow = 0;
			if (g == 0 && i >= MAX)  break;
			int x = g;
			if (i < b.s.size())  x += b.s[i];
			if (i < s.size())  x -= s[i];
			if (x < 0)  borrow = 1;
			if (i == MAX - 1)
				c.s.push_back(-x % BASE);
			else
				c.s.push_back((x + BASE) % BASE);
			g = x / BASE;
			if (borrow)  --g;
		}
		return c;
	}
}

BigInteger BigInteger::operator * (const BigInteger& b) const
{
	BigInteger c;
	c.s.clear();
	if (s.size() == 1 && s[0] == 0)
	{
		c.s.clear();
		c.s.push_back(0);
		return c;
	}
	if (b.s.size() == 1 && b.s[0] == 0)
	{
		c.s.clear();
		c.s.push_back(0);
		return c;
	}
	int MAX = max(s.size(), b.s.size());
	for (int i = 0; i < (MAX * 2 + 2); ++i)
		c.s.push_back(0);
	for (int i = 0; i < s.size(); ++i)
		for (int j = 0; j < b.s.size(); ++j)
		{
			c.s[i + j + 1] += c.s[i + j] / BASE;
			c.s[i + j] %= BASE;
			c.s[i + j] += s[i] * b.s[j];
		}
	for (int i = 0; i < (MAX * 2 + 1); ++i)
	{
		c.s[i + 1] += c.s[i] / BASE;
		c.s[i] %= BASE;
	}
	while (!*(c.s.end() - 1))
		c.s.erase(c.s.end() - 1);
	return c;
}

BigInteger BigInteger::operator / (const BigInteger& b) const
{
	if (b.s.size() == 1 && b.s[0] == 0)
	{
		cerr << "Exception has occured." << endl;
		cerr << "Arithmetic exception: Divided by Zero." << endl;
		exit(1);
	}
	BigInteger c;
	c.s.clear();
	BigInteger substraction = *this;
	BigInteger tmp;
	tmp.s.clear();
	tmp.s.push_back(1);
	if (substraction > b)
	{
		while (substraction >= b)
		{
			substraction -= b;
			if (substraction.s.size() > 1)
				while (!*(substraction.s.end() - 1))
					substraction.s.erase(substraction.s.end() - 1);
			c += tmp;
		}
	}
	else if (substraction == b)
		c.s.push_back(1);
	else
		c.s.push_back(0);
	return c;
}

BigInteger BigInteger::operator % (const BigInteger& b) const
{
	BigInteger c;
	c = *this - (*this / b) * b;
	return c;
}

BigInteger BigInteger::operator += (const BigInteger& b)
{
	*this = *this + b;
	return *this;
}

BigInteger BigInteger::operator -= (const BigInteger& b)
{
	*this = *this - b;
	return *this;
}

BigInteger BigInteger::operator *= (const BigInteger& b)
{
	*this = *this * b;
	return *this;
}

BigInteger BigInteger::operator /= (const BigInteger& b)
{
	*this = *this / b;
	return *this;
}

BigInteger BigInteger::operator %= (const BigInteger& b)
{
	*this = *this % b;
	return *this;
}

BigInteger BigInteger::fast_pow(BigInteger x, BigInteger y)
{
	BigInteger ans = 1;
	while (y > 0)
	{
		if (y.s[0] & 1)
			ans *= x;
		x *= x;
		y /= 2;
	}
	return ans;
}

注:算法竞赛入门经典真香!。。。
注2:除法现在慢的一批

发布了1 篇原创文章 · 获赞 0 · 访问量 7

猜你喜欢

转载自blog.csdn.net/doraJmon/article/details/105160332
今日推荐