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

📄 usuperint.cpp

📁 可以进行无限制的整数计算
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// USuperInt.cpp: implementation of the CUSuperInt class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "USuperInt.h"
#include "math.h"

#pragma warning(disable:4035)

/*
无符号大整数类
作者:缪元虎,四川绵阳供电局
myh9999@vip.sina.com
QQ:3977993
最后修改时间:2003-8-10
*/

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


//默认的最小长度(以双字为单位)
const DefaultLen = 1;

//设置能处理的最大整数长度(以双字为单位)
//即最大的整数为(下面是以指数形式表示的)
//      32*MaxLen
//     2           -1
//    2

//如果表示成10进制数,最大的数长度为
//MaxLen * 32 * log(2) / log(10) + 1;
//考虑到一个win32程序可用的内存空间名义上有4G,实际除了操作系统和一些额外开销,不足2G,
//一个DWORD占4字节,所有2G/4= 0x20000000;
//加上要运算,肯定有多个数,考虑MaxLen为0x1000000比较合适
//大约表示成十进制数有1.6亿位,已经非常大了。
const MaxLen = 0x1000000; 

//自定义的memcpy函数,用纯汇编编写,big.asm
//如果你只想用系统提供的函数,则请将下面的语句作为注释,再将再下面的语句注释符号取消
//这段代码作为使用汇编混合编程的演示(因为还有一些代码也可如此做,只是作者时间有限)
//big.asm用masm6.11编译生成了big.obj,在程序设置Link选项中Object/Libary Modules中加入big.obj
//编译使用的命令行是:ML /c /coff big.asm
extern "C" void MemCpy(DWORD* dst, DWORD* src, DWORD n);

//系统的memcpy函数
//#define MemCpy(dst, src, n)  memcpy(dst, src, n<<2)   	


//内联汇编编写的memcpy函数
/*
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:
	}
}
*/
CUSuperInt::CUSuperInt()
{
	pValue = new DWORD[len = DefaultLen];
	*pValue = 0;
	last = 1;
}

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

CUSuperInt::CUSuperInt(CUSuperInt &x)
{
	pValue = new DWORD[	len = x.len];
	MemCpy(pValue, x.pValue, last = x.last);
}

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

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

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

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


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

CUSuperInt& CUSuperInt::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;
}


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

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

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

CUSuperInt& CUSuperInt::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;
}

CUSuperInt& CUSuperInt::operator += (CUSuperInt& x)
{	
	Expand(x.len);
	last = max(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;
}

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

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

CUSuperInt& CUSuperInt::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 CUSuperInt::Compress()
{
	DWORD n = LeastOver(last);
	if (n < len)
	{
		DWORD *pTemp = new DWORD [len=n];
		MemCpy(pTemp, pValue, last);
		delete [] pValue;
		pValue = pTemp;
	}
}

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

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

inline DWORD CUSuperInt::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;
	}
}

void CUSuperInt::Debug()
{
	TRACE3("\r\nlen= %d,last= %d \r\nHex=%s\r\n",
		len, last, ToHexStr());
	TRACE1("Dec=%s\r\n",ToDecStr());	
}

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

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

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

CMyException::~CMyException()
{
	
}

CUSuperInt& CUSuperInt::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;
}

CUSuperInt CUSuperInt::operator /= (CUSuperInt& 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]);
	}

	//商数
	CUSuperInt 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),暂时为空,如需要再分配
	CUSuperInt* xx[32];
	xx[0] = new CUSuperInt(x);
	for (int i=1; i<32; i++)
	{
		xx[i] = NULL;
	}	

	//除数高位第一个1的位置(二进制)
	DWORD bit_x = x.pValue[x.last-1];
	__asm
	{
		bsr eax, bit_x;
		mov bit_x, eax
	}

	int nXX;  //减数在减数数组中的编号
	while (*this >= *xx[0])
	{			
		__asm
		{
			//计算出高DWORD中二进制位1的位置差
			mov ebx, this;
			mov esi, [ebx]this.pValue;
			mov ecx, [ebx]this.last;
			bsr eax, [esi][4*ecx-4];
			sub eax, bit_x;			
			add eax, 32;
			and eax, 0x1f;
			mov nXX, eax;

			//如果减数指针为空,则新分配
			mov eax, type xx;
			mul nXX;
			cmp xx[eax], 0;
			jne to_cmp;
		}

⌨️ 快捷键说明

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