⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bigint.h

📁 大整数类的汇编实现! 效率很高啊
💻 H
📖 第 1 页 / 共 2 页
字号:
/*
无符号大整数类
福州大学数计学院04研究生 彭小聪
04-11-28
高精度*高精度为O(N^2),需要改进,分治法或者fft(傅立叶快速变换);
*/

#ifndef BIG_INT
#define BIG_INT
#include "math.h"
#include <string>

#pragma warning(disable:4035)

typedef unsigned long DWORD;
typedef unsigned int UINT;
typedef unsigned char BYTE;
const DefaultLen = 1;
const MaxLen = 0x1000000;


class CBigInt
{
public:
	//构造及析构函数
	CBigInt();
	CBigInt(DWORD dwValue);
	CBigInt(char* pszVal);
	CBigInt(CBigInt& x);	
	virtual ~CBigInt();
public:
	//以下定义的是运算
	//重载的赋值运算符
	CBigInt& operator = (CBigInt& x);
	CBigInt& operator = (char* pszVal);
	CBigInt& operator = (DWORD dwValue);

	//重载的加法运算符
	CBigInt& operator += (CBigInt& x);
	CBigInt& operator += (DWORD dwValue);	
	CBigInt  operator + (CBigInt& x);
	CBigInt  operator + (DWORD dwValue);
	CBigInt  operator ++();			//++a
	CBigInt  operator ++(int);		//a++
	
	//重载的减法运算符,因为是无符号数,所以结果为大数减小数得到的差
	CBigInt& operator -= (CBigInt& x);
	CBigInt& operator -= (DWORD dwValue);
	CBigInt operator - (CBigInt& x);
	CBigInt operator - (DWORD dwValue);

	CBigInt&  operator --();			//--a
	CBigInt  operator --(int);		//a--

	//重载的乘法运算符
	CBigInt& operator *= (DWORD dwValue);
	CBigInt& operator *= (CBigInt& x);
	CBigInt  operator * (DWORD dwValue);
	CBigInt  operator * (CBigInt& x);

	//重载的除法运算符
	DWORD operator /= (DWORD dwValue); //返回余数
	CBigInt operator /= (CBigInt& x);//返回余数
	CBigInt operator / (DWORD dwValue); //返回商
	CBigInt operator / (CBigInt& x);//返回商

	CBigInt operator % (CBigInt& x);
	DWORD operator % (DWORD dwValue);

	//重载的比较运算符
	bool operator == (CBigInt& x);
	bool operator == (DWORD dwValue);
	bool operator != (CBigInt& x);
	bool operator != (DWORD dwValue);
	bool operator > (CBigInt& x);
	bool operator > (DWORD dwValue);
	bool operator >= (CBigInt& x);
	bool operator >= (DWORD dwValue);
	bool operator < (CBigInt& x);
	bool operator < (DWORD dwValue);
	bool operator <= (CBigInt& x);
	bool operator <= (DWORD dwValue);


	//乘2运算,即 	//  a =  a * 2^dwTimes; 相当于左移一位二进制,低位补0
	CBigInt& Double(DWORD dwTimes = 1);

	//除2运算; 相当于右移一位二进制,高位边补0,低位舍弃
	CBigInt& Half(DWORD dwTimes = 1);
public:
	//以下定义的是常用的操作
	//重新分配内存空间,用于增加数据长度,n为新长度
	void Expand(DWORD n);

	//压缩数据,以节省空间。指去掉高位多余的0。
	void Compress();	

	//转换在十六进制数字符串
	void ToHexStr(std::string& s);
	std::string ToHexStr();
	
	//转换成十进制数字符串
	void ToDecStr(std::string& s);
	std::string ToDecStr();

protected:
	//辅助函数
	inline DWORD LeastOver(DWORD n) ;//查找一个比n大,且为2^x次方的数

protected:
	DWORD *pValue;		//指向一个DWORD数组,用于存放数值
	DWORD len;			//DWORD数组的长度
	DWORD last;			//数组中的有效长度
};

const My_ErrorNo_OverFlow = 0;
const My_ErrorNo_ZeroByDiv = 1;
class CMyException  
{
public:
	CMyException(char* msg, UINT uErrorNo);
	virtual ~CMyException();
	char* m_szMsg;
	UINT  m_uErrorNo;
protected:
	CMyException(){}
};

void MemCpy(DWORD* dst, DWORD* src, DWORD n)
{
	__asm
	{
		mov ecx, n;
		jecxz to_end;	

		//保存方向标志
		pushf;	
		
		mov edi,dst;
		mov esi, src;
		cmp edi, esi;
		jbe to_up;	//dst <= src;
		
		mov eax, ecx;
		shl eax, 2;
		add eax, esi;
		cmp edi, eax;
		jae to_up;	//dst >= src+4n
		
		mov eax, ecx;
		dec eax;
		shl eax, 2;
		add edi, eax;
		add esi, eax;
		std;
		jmp to_mov;
to_up:
		cld;
to_mov:
		rep movsd;
		popf;
to_end:
	}
}

CBigInt::CBigInt()
{
	pValue = new DWORD[len = DefaultLen];
	*pValue = 0;
	last = 1;
}

CBigInt::~CBigInt()
{
	delete [] pValue;
}

CBigInt::CBigInt(CBigInt &x)
{
	pValue = new DWORD[	len = x.len];
	memset(&pValue[x.last],0,(len-x.last)*4);
	MemCpy(pValue, x.pValue, last = x.last);
}

CBigInt::CBigInt(DWORD dwValue)
{
	pValue = new DWORD[	len = DefaultLen];		
	*pValue = dwValue;
	last = 1;
}

CBigInt::CBigInt(char* pszVal)
{
	len = DefaultLen;
	pValue = new DWORD[len];
	operator = (pszVal);	
}

void CBigInt::Expand(DWORD n)
{
	if (n > MaxLen)
	{
		CMyException* exception = new CMyException("超过规定能处理的最大整数", My_ErrorNo_OverFlow);
		throw exception;
	}
	if (n > len)
	{
		DWORD* pTemp = new DWORD [len = n];
		memset(&pTemp[last], 0, (n-last)*4);
        len = n;
		MemCpy(pTemp, pValue, last);
		delete [] pValue;
		pValue = pTemp;
	}
}

CBigInt& CBigInt::operator = (CBigInt& x)
{
	if (this != &x)
	{
		if (len < x.last)
		{
			Expand(LeastOver(x.last));
		}
		MemCpy(pValue, x.pValue, last = x.last);
	}
	return *this;
}


CBigInt& CBigInt::operator = (DWORD dwValue)
{	
	*pValue = dwValue;
	last = 1;	
	return *this;
}

CBigInt& CBigInt::operator *= (DWORD dwValue)
{	
	if (dwValue == 0)
	{
		*pValue = 0;
		last = 1;	
	}
	else if (dwValue != 1)
	{
		DWORD times;
		__asm
		{
			bsr ebx, dwValue;
			bsf ecx, dwValue;
			cmp ebx, ecx;
			jne M0;				//如果是2的n次方,则使用移位的乘法
			mov times, ebx;
		}
		return Double(times);
		
M0:		
		DWORD dwFull;	
		__asm 
		{
			mov ebx, this;
			mov esi, [ebx]this.pValue;
			mov ecx, [ebx]this.last;
			mov ebx, dwValue;		//乘数
			xor edi, edi;			//作临时存贮器,保存高位
L1:		
			mov eax, [esi];
			mul ebx;
			add eax, edi;
			mov [esi], eax;
			adc edx, 0;
			mov edi, edx;
			add esi, 4;
			loop L1;
			
			cmp edi, 0;
			je L2;
			mov dwFull, edi;
		}
		if (last == len)
		{
			Expand(LeastOver(last+1));			
		}
		pValue[last++] = dwFull;
	}
L2:
	return *this;
}


CBigInt& CBigInt::operator *= (CBigInt& x)
{
	CBigInt a(*this);   
	CBigInt result;	
	a.Expand(LeastOver(x.last + last));
	result.Expand(LeastOver(x.last + last+1));  //不用this保存结果是因为考虑到x可能等于*this
	for (DWORD i=0; i<x.last; i++)
	{		
		result.operator += (a * x.pValue[i]);
		a.Double(32);
	}	
	return *this = result;
}

CBigInt CBigInt::operator * (CBigInt& x)  
{
	CBigInt a(*this);
	return a *= x;
}

CBigInt CBigInt::operator * (DWORD dwValue) 
{
	CBigInt a(*this);
	return a *= dwValue;
}

CBigInt& CBigInt::operator += (DWORD dwValue)
{
	__asm
	{		
		mov ebx, this;
		mov edi, [ebx]this.pValue;
		mov ecx, [ebx]this.last;		
		
		mov eax, dwValue;
		add [edi], eax;
		jnc L3;		
		
		mov edx, 1;
		jmp L2;
L1:  		
		add dword ptr[edi][edx*4], 1;
		jnc L3;
		inc edx;
L2:		
		loop L1;
	}
	if (last == len)
	{
		Expand(LeastOver(len+1));			
	}
	pValue[last++] = 1;		
L3:
	return *this;
}

CBigInt& CBigInt::operator += (CBigInt& x)
{	
	Expand(x.len);
	if(last<x.last)
		last=x.last;
	__asm
	{
		mov ebx, this;
		mov edi, [ebx]this.pValue;
		mov edx, x;
		mov esi, [edx]x.pValue;
		mov ecx, [edx]x.last;	
		xor edx, edx;		
		clc;
L1:	
		mov eax, [esi][edx*4];
		adc [edi][edx*4], eax;
		inc edx;
		loop L1;		
		jnc L4;
		
		mov ecx, [ebx]this.last;		//如果this的有效位更长,则加进位
		mov ebx, x;		
		sub ecx, [ebx]x.last;
		jz  L3;		
L2:
		add [edi][edx*4], 1;
		jnc L4;
		inc edx;
		loop L2;		
	}
L3:	
	if (last == len)
	{
		Expand(LeastOver(len+1));			
	}
	pValue[last++] = 1;
L4:	
	return *this;
}

CBigInt CBigInt::operator + (DWORD dwValue) 
{
	CBigInt a(*this);
	return a += dwValue;
}

CBigInt CBigInt::operator + (CBigInt& x)
{
	CBigInt a(*this);
	return a += x;
}

CBigInt& CBigInt::Double(DWORD dwTimes /*= 1*/)
{	
	if (dwTimes % 32 != 0)
	{
		DWORD dwFull = 0;
		__asm 
		{
			mov ebx, this;		
			mov edi, [ebx]this.pValue;
			mov ebx, [ebx]this.last;
			xor eax, eax;
			mov ecx, dwTimes;
L1:
			mov edx, [edi];		
			shld [edi], eax, cl;		
			mov eax, edx;
			add edi, 4;
			dec ebx;
			jnz L1;
			
			neg cl;
			shr edx, cl;
			jz L2;
			mov dwFull, edx;
		}
		if (len == last)
		{
			Expand(LeastOver(last+1));
		}
		pValue[last++] = dwFull;
	}
L2:	
	DWORD dwStep = dwTimes >> 5;  //除以32
	if (dwStep > 0)
	{
		Expand(LeastOver(last+dwStep));
		MemCpy(&pValue[dwStep], pValue, last);
		last += dwStep;
	}	
	return *this;
}

void CBigInt::Compress()
{
	DWORD n = LeastOver(last);
	if (n < len)
	{
		DWORD *pTemp = new DWORD [len=n];
		MemCpy(pTemp, pValue, last);
		delete [] pValue;
		pValue = pTemp;
	}
}

CBigInt CBigInt::operator ++(int)         //a++
{
	CBigInt a(*this);
	operator += (1);
	return a;
}

CBigInt  CBigInt::operator ++()			//++a
{
	return operator += (1);
}

inline DWORD CBigInt::LeastOver(DWORD n)
{	
	__asm
	{
		bsr ebx, n;
		bsf ecx, n;
		cmp ebx, ecx;
		je  to_set;
		inc ebx;
to_set:
		xor eax, eax;
		bts eax, ebx;
	}
}

//////////////////////////////////////////////////////////////////////
// CMyException Class
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMyException::CMyException(char* msg, UINT uErrorNo)
{
	m_szMsg = msg;
	m_uErrorNo = uErrorNo;
}

CMyException::~CMyException()
{
	
}

CBigInt& CBigInt::Half(DWORD dwTimes /*= 1*/)
{	
	DWORD dwStep = dwTimes / 32;
	if (dwStep >= last)
	{
		*pValue = 0;
		last = 1;
		return *this;
	}
	else if (dwStep > 0)
	{
		MemCpy(pValue, &pValue[dwStep], last-=dwStep);
	}	
	if (dwTimes % 32 != 0)
	{
		__asm 
		{
			mov ebx, this;		
			mov edi, [ebx]this.pValue;
			mov ebx, [ebx]this.last;			
			dec ebx;
			mov ecx, dwTimes;
			xor edx, edx;
L1: 			
			cmp ebx, edx;
			je  L2;
			mov eax, 4[edi][edx*4];		
			shrd [edi][edx*4], eax, cl;
			inc edx;
			jmp L1;
L2:
			xor eax, eax;
			shrd [edi][edx*4], eax, cl;
		}
		if (last > 1 && pValue[last-1] == 0)
		{     
			last --;				
		}	
	}
	return *this;
}

CBigInt CBigInt::operator /= (CBigInt& x)//返回余数
{
	if (x == 0)		//除数为0
	{
		CMyException* exception = new CMyException("除数为0", My_ErrorNo_ZeroByDiv);
		throw exception;		
	}

	if (*this == 0 || x == 1)//被除数为0或除数为1
	{
		return *this;
	}

	if (x.last == 1)	//除数为DWORD时
	{
		return operator /= (x.pValue[0]);
	}

	//商数
	CBigInt r;
	r.Expand(LeastOver(last-x.last+1));
	r.last = last- x.last + 1;
	memset(r.pValue, 0, 4*r.len);

	//减数数组,分别为x*2^i, (i从0到31),暂时为空,如需要再分配
	CBigInt* xx[32];
	xx[0] = new CBigInt(x);
	for (int i=1; i<32; i++)
	{
		xx[i] = NULL;
	}	

	//除数高位第一个1的位置(二进制)
	DWORD bit_x = x.pValue[x.last-1];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -