|
[这个贴子最后由pdshjf在 2008/11/19 08:17pm 第 1 次编辑]
以下是我二月份写的一个C++大数计算类,请大家多提宝贵意见!
#include "StdAfx.h"
#include ".\super.h"
Super::Super()
{
BitLength = 0;
Fat = NULL;
}
Super::Super(UINT val)
{
BitLength = 1;
Fat = new UINT[BitLength];
if(Fat == NULL)throw "Memory error!";
Fat[0] = val;
}
Super::Super(Super &val)
{
BitLength = val.BitLength;
Fat = new UINT[BitLength];
if(Fat == NULL)throw "Memory error!";
memcpy(Fat,val.Fat,BitLength*sizeof(UINT));
}
//接收一个字符串,以前缀0x来判断是十进制还是十六进制
Super::Super(char* val)
{
UINT len = UINT(strlen(val));
char ch;
BYTE* tmp;
if(val[0] == ';0'; && val[1] == ';x'; || val[1] == ';X';)
{
UINT j = 0;
BitLength = ((len-1)/2+(sizeof(UINT)-1))/sizeof(UINT);
Fat = new UINT[BitLength];
if(Fat == NULL)throw "Memory error!";
memset(Fat,0,BitLength*sizeof(UINT));
tmp = (BYTE*)Fat;
for(int i=len-1;i>=2;i--)
{
if(val>=';0'; && val<=';9';)
{
if(j%2 == 0)
tmp[j/2] = val & 0x0f;
else
tmp[j/2] |= (val & 0x0f)<<4;
}
else
{
ch = val | 0x20;
if(ch>=';a'; && ch<=';f';)
{
if(j%2 == 0)
tmp[j/2] = (val & 0x0f) + 9;
else
tmp[j/2] |= ((val & 0x0f) + 9) << 4;
}
else
{
delete []Fat;
Fat = NULL;
throw "String Valuse Erroe!";
return;
}
}
j++;
}
}
else
{
Super rank(1);
BitLength = 1;
Fat = new UINT[BitLength];
if(Fat == NULL)throw "Memory error!";
Fat[0] = 0;
for(int i=len-1;i>=0;i--)
{
if(val>=';0'; && val<=';9';)
{
*this = *this + Super(UINT(val&0x0f))*rank;
}
else
{
delete []Fat;
Fat = NULL;
throw "String Valuse Erroe!";
return;
}
rank = rank * 10;
}
}
}
Super::~Super(void)
{
if( Fat != NULL)delete []Fat;
}
void Super:perator =(Super val)
{
if(BitLength != val.BitLength)
{
if (Fat != NULL)delete []Fat;
BitLength = val.BitLength;
Fat = new UINT[BitLength];
if(Fat == NULL)throw "Memory error!";
}
memcpy(Fat,val.Fat,BitLength*sizeof(UINT));
}
Super Super:perator+(Super val)
{
Super result;
if(BitLength < val.BitLength)
result.BitLength = val.BitLength + 1;
else
result.BitLength = BitLength + 1;
result.Fat = new UINT[result.BitLength];
if(result.Fat == NULL)throw "Memory error!";
memset(result.Fat,0,result.BitLength*sizeof(UINT));
for(UINT i=0;i<result.BitLength-1;i++)
{
if(i>=BitLength)
{
result.Fat = result.Fat + val.Fat;
continue;
}
if(i>=val.BitLength)
{
result.Fat = result.Fat + Fat;
continue;
}
result.Fat = result.Fat + Fat + val.Fat;
if(result.Fat<Fat && result.Fat<val.Fat)
result.Fat[i+1] = 1;
}
for(UINT i=result.BitLength-1;i>0;i--)
{
if(result.Fat == 0)
result.BitLength--;
else
break;
}
return result;
}
Super Super:perator-(Super val)
{
Super result;
UINT overflow = 0;
if(Compare(&val) >= 0)
{
result.BitLength = BitLength;
result.Fat = new UINT[result.BitLength];
if(result.Fat == NULL)throw "Memory error!";
memset(result.Fat,0,result.BitLength*sizeof(UINT));
}
else
{
throw "Be Subtrahend Oversize";
return result;
}
for(UINT i=0;i<result.BitLength;i++)
{
if(i<val.BitLength)
result.Fat = Fat - val.Fat - overflow;
else
result.Fat = Fat - overflow;
if(overflow)
{
if (result.Fat >= Fat)
overflow = 1;
else
overflow = 0;
}
else
{
if (result.Fat > Fat)
overflow = 1;
else
overflow = 0;
}
}
for(UINT i=result.BitLength-1;i>0;i--)
{
if(result.Fat == 0)
result.BitLength--;
else
break;
}
return result;
}
Super Super ::operator*(Super val)
{
Super result;
UINT i,j,tmp;
__int64 a;
if(val == UINT(0) || *this == UINT(0)) return UINT(0);
result.BitLength = BitLength + val.BitLength;
result.Fat = new UINT[result.BitLength];
if(result.Fat == NULL)throw "Memory error!";
memset(result.Fat,0,result.BitLength*sizeof(UINT));
//做移位乘法运算
tmp = 0;
for(i=0;i<val.BitLength;i++)
{
for(j=0;j<BitLength;j++)
{
a = Fat[j];
a *= val.Fat;
tmp = UINT(result.Fat[j+i] + a);
if(tmp < result.Fat[j+i])
result.Fat[j+i+1]++;
result.Fat[j+i] = tmp;
tmp = UINT(result.Fat[j+i+1] + (a>>32));
if(tmp < result.Fat[j+i+1])
result.Fat[j+i+2]++;
result.Fat[j+i+1] = tmp;
}
}
for(UINT i=result.BitLength-1;i>0;i--)
{
if(result.Fat == 0)
result.BitLength--;
else
break;
}
return result;
}
Super Super::operator/(Super val)
{
Super result,tmp,move;
UINT count = 0;
UINT i,j,bitmove,mul;
UINT uint_bit = sizeof(UINT)*8;
int S;
//判断除数是否为0
if(val.BitLength == 1 && val.Fat[0] == 0)
{
throw "Divisor is zero";
return result;
}
//如果除数大于被除数直接返回0
S = val.Compare(this);
if(S == 1) return UINT(0);
if(S == 0) return UINT(1);
//计算除数有效位
bitmove = 1<<(uint_bit-1);
mul = val.Fat[val.BitLength-1];
for(i=0;i<uint_bit;i++)
{
if((mul & (bitmove>>i))==0)count++;
else break;
}
count = val.BitLength * uint_bit - count;
//初化结果
result.BitLength = BitLength - val.BitLength + 1;
result.Fat = new UINT[result.BitLength];
if(result.Fat == NULL)throw "Memory error!";
memset(result.Fat,0,result.BitLength*sizeof(UINT));
//初化减数
move.BitLength = this->BitLength;
move.Fat = new UINT[move.BitLength];
if(move.Fat == NULL)throw "Memory error!";
//初始化被除数、除数和商值
bitmove = 1;
tmp = *this;
do
{
//查找被除数最高有效位
i = tmp.BitLength * uint_bit;
bitmove = 1<<(uint_bit-1);
mul = tmp.Fat[tmp.BitLength-1];
for(j=0;j<uint_bit;j++)
{
if((mul & (bitmove>>j)) == 0)i--;
else break;
}
if(i<count)break;
i -= count;
LOOP:
//确定减数的位置
memset(move.Fat,0,move.BitLength*sizeof(UINT));
for(UINT k=0;k<val.BitLength;k++)
{
move.Fat[i/uint_bit+k] += val.Fat[k]<<(i%uint_bit);
if(i%uint_bit)
if(val.Fat[k] >> (uint_bit-(i%uint_bit)))
move.Fat[i/uint_bit+k+1] = val.Fat[k]>>(uint_bit-(i%uint_bit));
}
for(UINT k=move.BitLength-1;k>0;k--)
{
if(move.Fat[k] ==0)move.BitLength--;
else break;
}
S = tmp.Compare(&move);
if(S == 1)
{
tmp = tmp - move;
result.Fat[i/uint_bit] |= 1 << (i%uint_bit);
}
if(S == 0)
{
result.Fat[i/uint_bit] |= 1 << (i%uint_bit);
break;
}
if(S == -1)
{
if(i == 0) break;
i--;
goto LOOP;
}
}while(i>0);
//规格化结果数据
for(i=result.BitLength-1;i>0;i++)
{
if(result.Fat == 0)result.BitLength --;
else break;
}
return result;
}
Super Super::operator%(Super val)
{
Super result,move;
UINT count = 0;
UINT i,j,bitmove,mul;
UINT uint_bit = sizeof(UINT)*8;
int S;
//判断除数是否为0
if(val.BitLength == 1 && val.Fat[0] == 0)
{
throw "Divisor is zero";
return result;
}
//如果除数大于被除数直接返回0
S = val.Compare(this);
if(S == 1) return *this;
if(S == 0) return UINT(0);
//计算除数有效位
bitmove = 1<<(uint_bit-1);
mul = val.Fat[val.BitLength-1];
for(i=0;i<uint_bit;i++)
{
if((mul & (bitmove>>i))==0)count++;
else break;
}
count = val.BitLength * uint_bit - count;
//初化结果
result = *this;
//初化减数
move.BitLength = this->BitLength;
move.Fat = new UINT[move.BitLength];
if(move.Fat == NULL)throw "Memory error!";
//初始化被除数、除数和商值
bitmove = 1<<(uint_bit-1);
do
{
//查找被除数最高有效位
i = result.BitLength * uint_bit;
mul = result.Fat[result.BitLength-1];
for(j=0;j<uint_bit;j++)
{
if((mul & (bitmove>>j)) == 0)i--;
else break;
}
if(i<count)break;
i -= count;
LOOP:
//确定减数的位置
memset(move.Fat,0,move.BitLength*sizeof(UINT));
for(UINT k=0;k<val.BitLength;k++)
{
move.Fat[i/uint_bit+k] += val.Fat[k]<<(i%uint_bit);
if(i%uint_bit)
if(val.Fat[k] >> (uint_bit-(i%uint_bit)))
move.Fat[i/uint_bit+k+1] = val.Fat[k]>>(uint_bit-(i%uint_bit));
}
for(UINT k=move.BitLength-1;k>0;k--)
{
if(move.Fat[k] ==0)move.BitLength--;
else break;
}
S = result.Compare(&move);
if(S == -1)
{
if(i==0)break;
i--;
goto LOOP;
}
if(S == 0)
{
result = result - move;
break;
}
result = result - move;
}while(i>0);
//规格化结果数据
for(i=result.BitLength-1;i>0;i++)
{
if(result.Fat == 0)result.BitLength --;
else break;
}
return result;
}
int Super::Compare(Super *val)
{
if(BitLength > val->BitLength)return 1;
if(BitLength < val->BitLength)return -1;
for(int i=BitLength-1;i>=0;i--)
{
if(Fat == val->Fat)continue;
if(Fat > val->Fat)return 1;
if(Fat < val->Fat)return -1;
}
return 0;
}
BOOL Super::operator ==(Super val)
{
if(BitLength != val.BitLength)return FALSE;
for(int i=BitLength-1;i>=0;i--)
{
if(Fat == val.Fat)continue;
if(Fat != val.Fat)return FALSE;
}
return TRUE;
}
BOOL Super::operator >(Super val)
{
if(BitLength > val.BitLength)return TRUE;
if(BitLength < val.BitLength)return FALSE;
for(int i=BitLength-1;i>=0;i--)
{
if(Fat > val.Fat)return TRUE;
if(Fat < val.Fat)return FALSE;
}
return FALSE;
}
BOOL Super::operator <(Super val)
{
if(BitLength > val.BitLength)return FALSE;
if(BitLength < val.BitLength)return TRUE;
for(int i=BitLength-1;i>=0;i--)
{
if(Fat > val.Fat)return FALSE;
if(Fat < val.Fat)return TRUE;
}
return FALSE;
}
BOOL Super::IsEmpty()
{
if(BitLength == 0 || Fat == NULL) return TRUE;
else return FALSE;
}
char* Super::Outstr(HD hd)
{
if(hd == Hex)
{
UINT len = BitLength*sizeof(UINT);
char *result = new char[len*2+1];
result[len*2] = 0;
BYTE* po = (BYTE*)Fat;
po = po + len-1;
for(UINT i=0;i<len;i++)
{
if((*po >> 4) > 9)
result[i*2] = (*po >> 4) - 10 + ';A';;
else
result[i*2] = (*po >> 4) + ';0';;
if((*po & 0x0f) > 9)
result[i*2+1] = (*po & 0x0f) - 10 + ';A';;
else
result[i*2+1] = (*po & 0x0f) + ';0';;
po--;
}
return result;
}
else
{
UINT len = BitLength * sizeof(UINT);
char *tmp = new char[len*3];
Super C,T;
UINT i=0;
C = *this;
while(C > UINT(0))
{
T = C % 10;
C = C / 10;
tmp = char(T.Fat[0] + ';0';);
i++;
}
tmp = 0;
char * result = new char[i+1];
result = 0;
for(UINT j=0;j<i;j++)
result[j] = tmp[i-j-1];
delete []tmp;
return result;
}
}
|
|