大数类

虽然好多人写过了,但有段时间实在没事干,想着把以前写过基于string一个个bit计算的给改改。

基本功能都有,有一些简单测试,但不保证无bug

h文件:

#pragma once
#include <exception>
#include <string>
using namespace std;

class BiException : public std::exception
{
public:
	BiException(const char* msg)
		: exception(msg)
	{

	}

};

class BigInteger
{
	int m_bit[200];
	bool m_sig;
	int m_high;
	int m_base;
	int m_low;
	const static int max_number = 10000;
	friend struct SigTemp;
private:
	struct SigTemp 
	{
		SigTemp(const BigInteger& bi);
		~SigTemp();
		BigInteger* p;
	};
private:
	void set(__int64 n);
	bool set(const string& str);

	BigInteger abs_add(const BigInteger& bi) const;
	BigInteger abs_sub(const BigInteger& bi) const;

	BigInteger add(const BigInteger& bi) const;
	BigInteger sub(const BigInteger& bi) const;

	BigInteger& shift(int i);
	BigInteger mul(int n) const;
	BigInteger mul(const BigInteger& bi) const;

	int trydiv(const BigInteger& bi);
	BigInteger _div(const BigInteger& bi, bool mod, bool print = false) const;
	BigInteger div(const BigInteger& bi, bool print = false) const;

	BigInteger mod(const BigInteger& bi, bool print = false) const;

	int compare(const BigInteger& rhs) const;
	int abs_compare(const BigInteger& rhs) const;
public:
	int length() const { return m_high - m_low; }

public:
	BigInteger(__int64 n = 0);
	BigInteger(const string& str);

	BigInteger& operator = (__int64 n);
	BigInteger& operator = (const string& str);

	string tostring() const;
	BigInteger set_sig(bool minus = true) ;


	BigInteger& operator += (const BigInteger& rhs);
	BigInteger& operator -= (const BigInteger& rhs);
	BigInteger& operator *= (const BigInteger& rhs);
	BigInteger& operator /= (const BigInteger& rhs);
	BigInteger& operator %= (const BigInteger& rhs);
	BigInteger& operator -();

#define MARCO_OP(ret, op) friend ret operator op (const BigInteger& lhs, const BigInteger& rhs)

	MARCO_OP(BigInteger, +);
	MARCO_OP(BigInteger, -);
	MARCO_OP(BigInteger, *);
	MARCO_OP(BigInteger, /);
	MARCO_OP(BigInteger, %);

	MARCO_OP(bool, <);
	MARCO_OP(bool, <=);
	MARCO_OP(bool, >);
	MARCO_OP(bool, >=);
	MARCO_OP(bool, ==);
	MARCO_OP(bool, !=);

#undef MARCO_OP

	
	friend ostream& operator <<(ostream& o, const BigInteger& bi);

	friend void test_biginteger();
};
inline BigInteger operator + (const BigInteger& lhs, const BigInteger& rhs)
{
	return lhs.add(rhs);
}
inline BigInteger operator - (const BigInteger& lhs, const BigInteger& rhs)
{
	return lhs.sub(rhs);
}
inline BigInteger operator * (const BigInteger& lhs, const BigInteger& rhs)
{
	return lhs.mul(rhs);
}
inline BigInteger operator / (const BigInteger& lhs, const BigInteger& rhs)
{
	return lhs.div(rhs);
}
inline BigInteger operator % (const BigInteger& lhs, const BigInteger& rhs)
{
	return lhs.mod(rhs);
}
inline ostream& operator <<(ostream& o, const BigInteger& bi)
{
	o<<bi.tostring();
	return o;
}
inline bool operator < (const BigInteger& lhs, const BigInteger& rhs)
{
	return lhs.compare(rhs) < 0;
}
inline bool operator <= (const BigInteger& lhs, const BigInteger& rhs)
{
	return lhs.compare(rhs) <= 0;
}
inline bool operator > (const BigInteger& lhs, const BigInteger& rhs)
{
	return lhs.compare(rhs) > 0;
}
inline bool operator >= (const BigInteger& lhs, const BigInteger& rhs)
{
	return lhs.compare(rhs) >= 0;
}
inline bool operator == (const BigInteger& lhs, const BigInteger& rhs)
{
	return lhs.compare(rhs) == 0;
}
inline bool operator != (const BigInteger& lhs, const BigInteger& rhs)
{
	return lhs.compare(rhs) != 0;
}
inline BigInteger makeint64(const BigInteger& high, const BigInteger& low)
{
	return (high * (BigInteger((__int64)1 << 32))) + low;
}

void test_biginteger();


cpp文件


#include "StdAfx.h"
#include "BigInteger.h"
#include <assert.h>

//

BigInteger::SigTemp::SigTemp(const BigInteger& bi)
	: p(NULL)
{
	if(bi.m_sig) return;

	p = const_cast<BigInteger*>(&bi);
	p->set_sig(false);
}
BigInteger::SigTemp::~SigTemp()
{
	if(p) p->set_sig(true);
}


//
BigInteger::BigInteger(__int64 n)
{			
	set(n);
}
BigInteger::BigInteger(const string& str)
{			
	set(str);
}
BigInteger& BigInteger::operator = (__int64 n)
{
	set(n);
	return *this;
}
BigInteger& BigInteger::operator = (const string& str)
{
	set(str);
	return *this;
}
string BigInteger::tostring() const
{
	string ret = m_sig ? "" : "-";
	char buf[8];
	for(int i = m_high - 1 ; i >= m_low ; -- i)
	{
		sprintf(buf, (i == m_high - 1)? "%d" : "%04d", m_bit[i]);
		ret += buf;
	}
	return ret.empty() ? "0" : ret;
}
BigInteger BigInteger::set_sig(bool minus) 
{ 
	m_sig = !minus;
	return *this;
}

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

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

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

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

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

BigInteger& BigInteger::operator -()
{
	m_sig = !m_sig;
	return *this;
}

void BigInteger::set(__int64 n)
{
	memset(this, 0, sizeof(BigInteger));

	m_sig = n >= 0;

	m_low = m_high = m_base = 100;

	__int64 carry = n < 0 ? -n : n;
	int i = m_base;
	for( ; carry ; ++ i)
	{
		m_bit[i] = carry % (__int64)max_number;
		carry /= (__int64)max_number;
	}
	if(i > m_high) m_high = i;
}
bool BigInteger::set(const string& str)
{
	int len = str.length();
	if(len == 0) return false;

	memset(this, 0, sizeof(BigInteger));
	m_low = m_high = m_base = 100;
	m_sig = (str[0] != '-');
	
	int low = m_sig ? 0 : 1, tmp = 0, bit = 1, i = m_base, j = len - 1;
	for( ; ; -- j)
	{
		if(!isdigit(str[j])) return false;

		tmp += bit * (str[j] - '0');
		bit *= 10;
		if(j == low) 
		{
			m_bit[i++] = tmp;
			break;
		}
		if(tmp > max_number / 10)
		{
			m_bit[i++] = tmp;
			bit = 1;
			tmp = 0;
		}
	}
	if(i > m_high) m_high = i;

	return true;
}
BigInteger BigInteger::abs_add(const BigInteger& bi) const
{
	if(bi.length() == 0) return *this;

	BigInteger result(*this);
	int i = result.m_low, j = bi.m_low, carry = 0, tmp = 0;
	do
	{
		tmp = carry + result.m_bit[i] + bi.m_bit[j];
		result.m_bit[i] = tmp % max_number;
		carry = tmp / max_number;

		++i,++j;
	}while(i < result.m_high || j < bi.m_high || carry);

	if(i > result.m_high) result.m_high = i;

	return result;
}
BigInteger BigInteger::abs_sub(const BigInteger& bi) const
{
	if(bi.length() == 0) return *this;

	BigInteger result(*this);

	int i = result.m_low, j = bi.m_low, carry = 0, tmp = 0, zerobit = result.m_low, nonzerobit = result.m_low;
	do
	{
		tmp = carry + result.m_bit[i] - bi.m_bit[j];
		carry = 0;
		if(tmp == 0)
		{
			zerobit = i;
		}
		else
		{
			nonzerobit = i;
			if(tmp < 0) 
			{
				tmp += max_number;
				carry = -1;
			}
		}
		result.m_bit[i] = tmp;
		++i,++j;
	}while((i < result.m_high && j < bi.m_high) || carry);

	if(i == result.m_high && zerobit > nonzerobit) 
		result.m_high = nonzerobit + 1;
	return result;
}
BigInteger BigInteger::add(const BigInteger& bi) const
{
	if(bi.length() == 0) return *this;

	if(m_sig != bi.m_sig)
	{
		BigInteger result;

		int ret = abs_compare(bi);
		if(ret == 0) return result;
		if(ret == -1) 
		{
			result = bi.sub(*this);
			if(m_sig) result.m_sig = false;

		}
		else
		{
			result = sub(bi);
			if(!m_sig) result.m_sig = false;
		}
		return result; 
	}
	return abs_add(bi);
}
BigInteger BigInteger::sub(const BigInteger& bi) const
{
	if(bi.length() == 0) return *this;

	if(m_sig) // +
	{
		// -
		if(!bi.m_sig) return abs_add(bi);

		// +
		int ret = abs_compare(bi);
		if(ret < 0) return bi.abs_sub(*this).set_sig();
		if(ret == 0) return 0;
		return abs_sub(bi);
	}

	// -
	// +
	if(bi.m_sig) return abs_add(bi);

	// -
	int ret = abs_compare(bi);
	if(ret < 0) return bi.abs_sub(*this).set_sig(false);
	if(ret == 0) return 0;
	return abs_sub(bi);
}
BigInteger& BigInteger::shift(int i)
{
	if(length() == 0) return *this;
	m_low -= i;
	return *this;
}
BigInteger BigInteger::mul(int n) const
{
	if(n == 0) return BigInteger(0);

	BigInteger result(*this);
	int i = result.m_base, carry = 0, tmp = 0;
	while((tmp = result.m_bit[i] * n + carry) || i < result.m_high) 
	{
		result.m_bit[i] = tmp % max_number;	
		carry = tmp / max_number;

		++i;
	}

	if(i > result.m_high) result.m_high = i;

	return result;
}
BigInteger BigInteger::mul(const BigInteger& bi) const
{
	BigInteger result;
	if(bi.m_high - bi.m_low == 0) return result;

	bool sig = !(m_sig ^ bi.m_sig);
	SigTemp o(bi);
	for(int i = bi.m_base ; i < bi.m_high ; ++ i)
	{
		result += (mul(bi.m_bit[i]).shift(i - bi.m_base));
	}
	result.m_sig = sig;
	return result;
}
int BigInteger::trydiv(const BigInteger& bi)
{
	assert(abs_compare(bi) >= 0);

	int l = 1, h = 9999, c = h - l + 1, comp = 0;
	while(c)
	{
		int c2 = c / 2;
		int mid = l + c2;
		comp = abs_compare(bi.mul(mid));
		if(comp < 0)
		{
			c = c2;
		}
		else if(comp > 0)
		{
			l = mid + 1;
			c = c2 - 1;
		}
		else
			return mid;
	}
	BigInteger tmp = bi.mul(l);
	int ret = abs_compare(tmp);
	if(ret > 0)
	{
		while(abs_compare(tmp += bi) >= 0 && ++ l);

		return l;
	}
	else
	{
		while(-- l && abs_compare(tmp -= bi) <= 0);

		return l;
	}
	return l;
}
BigInteger BigInteger::_div(const BigInteger& bi, bool mod, bool print) const
{
	if(bi.abs_compare(0) == 0) throw BiException("Div by zero!");
	if(abs_compare(0) == 0) return BigInteger(0);

	int ret = abs_compare(bi);
	if(ret < 0) return BigInteger(0);
	if(ret == 0) return BigInteger(!(m_sig ^ bi.m_sig));

	bool sig = !(m_sig ^ bi.m_sig);
	SigTemp o(bi);

	BigInteger tmp, result;
	for(int i = m_high - 1 ; i >= m_base ; -- i)
	{
		tmp.shift(1) += m_bit[i];
		int ret = tmp.abs_compare(bi);
		if(ret == -1)
		{
			if(i != m_high - 1)
			{
				result.shift(1);
			}
			continue;
		}
		if(ret == 0)
		{
			result = result.shift(1).add(1);
			tmp.set(0);
		}
		else
		{
			int trydiv = tmp.trydiv(bi);
			if(print)
			{
				printf("%s trydiv %s, 商 = %d",tmp.tostring().c_str(), bi.tostring().c_str(), trydiv);
			}
			result = result.shift(1).add(trydiv);
			tmp -= bi.mul(trydiv);
			if(print)
				printf("余数 = %s\n", tmp.tostring().c_str());
		}
	}
	if(!mod)
		result.m_sig = sig;

	return mod ? tmp : result;
}
BigInteger BigInteger::div(const BigInteger& bi, bool print) const
{
	return _div(bi, false, print);
}

BigInteger BigInteger::mod(const BigInteger& bi, bool print) const
{
	return _div(bi, true, print);
}

int BigInteger::compare(const BigInteger& rhs) const
{
	if(m_sig != rhs.m_sig) return (int)m_sig - (int)rhs.m_sig;

	return abs_compare(rhs);
}
int BigInteger::abs_compare(const BigInteger& rhs) const
{
	int l1 = length(), l2 = rhs.length();
	if(l1 != l2) return l1 < l2 ? -1 : 1;

	for(int i = m_high - 1, j = rhs.m_high - 1 ; i >= m_low ; -- i, -- j)
	{
		if(m_bit[i] != rhs.m_bit[j]) 
			return m_bit[i] < rhs.m_bit[j] ? -1 : 1;
	}
	return 0;
}

//test
//
#define MAKE_INT64(h, l) (__int64)((l) | ((__int64)h << 32))

#include <iostream>
#include <time.h>
#include <windows.h>
using namespace std;

void test_biginteger()
{

#if 0
	BigInteger b1(-32889549839), b2(-9839);
	cout<<b2-b1<<endl;
	return;
#endif
	srand((unsigned int)time(0));
	BigInteger bi1, bi2, bi3, bi4;
	DWORD t = GetTickCount();
	for(int i = 0 ; i < 100000 ; ++ i)
	{			
		int l = rand(),h = rand();
		__int64 x = MAKE_INT64(h, l);

		bi1 = l, bi2 = h;
		bi3 = makeint64(h, l);

		if(!(bi3.compare(x) == 0))
			printf("error\n");

		l = rand(), h = rand();
		__int64 y = (__int64)l * (__int64)h;

		bi1 = l, bi2 = h;
		bi4 = bi1 * bi2;

		if(!(bi4.compare(y) == 0))
			printf("error\n");

		if(rand() & 1)
		{
			bi4.set_sig();
			y = -y;
		}
		if(rand() & 1)
		{
			bi3.set_sig();
			x = -x;
		}
		int t = 2;//rand() % 3;
		switch(t)
		{
		case 0:
			{
				if((bi4 + bi3).compare(x + y) != 0)
					printf("error\n");
			}
			break;
		case 1:
			{

				if((bi4 - bi3).compare(y - x) != 0)
					printf("error\n");

			}
			break;
		case 2:
			{
				if(bi4.compare(bi3) > 0)
				{
					if(x == 0) continue;
					if((bi4 / bi3).compare(y / x) != 0)
					{
						printf("error\n");
						bi4.div(bi3, true);
						cout<<bi4<<" / "<<bi3<<" : ";
						cout<<"shoule be "<< y/x<<", infact = "<<(bi4/bi3).tostring()<<endl;
						int a = 1;
					}
				}
				else
				{
					if(y == 0) continue;
					if((bi3 / bi4).compare(x / y) != 0)
					{
						printf("error\n");
						bi3.div(bi4, true);
						cout<<bi3<<" / "<<bi4<<" : ";
						cout<<"shoule be "<< x/y<<", infact = "<<(bi3/bi4).tostring()<<endl;
						int a = 1;
					}
				}
			}
			break;
		default:
			break;
		}

	}
	cout<<__FUNCTION__<<" cost "<<GetTickCount() - t<<" ms.\n";
}



深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值