- Joined
- May 1, 2009
- Messages
- 2
- Reaction score
- 0
Does aNY1 have C++ code they wrote themself that can add 2 integers of ANY size together ? and show the answer in HEX?
#define BIGINT_E_OUTOFMEMORY -1
#define BIGINT_DATATYPE unsigned __int32
#define BIGINT_DATATYPE_MAX 0xFFFFFFFF
#define BIGINT_BYTES 4
#define BIGINT_BITS 32
#define BIGINT_ALLOCATE_BY 256
class BigInt
{
protected:
BIGINT_DATATYPE *data;
__int32 dataused, dataallocated;
public:
void SetDataSize(const BIGINT_DATATYPE size)
{
int a = (size+BIGINT_ALLOCATE_BY-1)/BIGINT_ALLOCATE_BY;
if (a<1)
a=1;
a*=BIGINT_ALLOCATE_BY*BIGINT_BYTES;
if (this->data && this->dataallocated==a/BIGINT_BYTES)
return;
BIGINT_DATATYPE *newdata = (BIGINT_DATATYPE *)malloc(a);
if (!newdata)
throw BIGINT_E_OUTOFMEMORY;
Zero(newdata, a/BIGINT_BYTES);
if (this->data)
{
CopyMemory(newdata, this->data, this->dataallocated*BIGINT_BYTES>a?a:this->dataallocated*BIGINT_BYTES);
free(this->data);
}
this->data=newdata;
this->dataallocated=a/BIGINT_BYTES;
}
void Shrink()
{
while (this->dataused && !this->data[this->dataused-1])
--this->dataused;
}
static void Zero(void *p, int num)
{
if (!num)
return;
__asm
{
cld
mov ecx,num
xor eax,eax
mov edi,p
rep stosd
}
}
void ZeroUsed()
{
int x=this->dataused;
if (!x)
return;
void *p=this->data;
__asm
{
cld
mov ecx,x
xor eax,eax
mov edi,p
rep stosd
}
this->dataused=0;
}
void ZeroAllocated()
{
int x=this->dataallocated;
if (!x)
return;
void *p=this->data;
__asm
{
cld
mov ecx,x
xor eax,eax
mov edi,p
rep stosd
}
this->dataused=0;
}
void Swap(BigInt &value)
{
int da, du;
BIGINT_DATATYPE *p;
da=value.dataallocated;
du=value.dataused;
p=value.data;
value.dataallocated=this->dataallocated;
value.dataused=this->dataused;
value.data=this->data;
this->dataallocated=da;
this->dataused=du;
this->data=p;
}
int BitCount()
{
Shrink();
if (!this->dataused)
return 0;
int count=BIGINT_BITS;
BIGINT_DATATYPE a = this->data[this->dataused-1];
for (int x=0; x<BIGINT_BITS; ++x)
if (a & 0x80000000)
return ((this->dataused-1)*BIGINT_BITS)+count;
else
{
--count;
a<<=1;
}
return ((this->dataused-1)*BIGINT_BITS)+count;
}
~BigInt()
{
if (data)
free(data);
}
BigInt()
{
data=0;
dataallocated=0;
dataused=0;
SetDataSize(BIGINT_ALLOCATE_BY);
}
BigInt(const BigInt &value)
{
data=0;
dataallocated=0;
dataused=value.dataused;
SetDataSize(value.dataallocated);
if (value.dataused)
CopyMemory(data, value.data, value.dataused*BIGINT_BYTES);
}
BigInt(const __int32 value)
{
data=0;
dataallocated=0;
if (value)
dataused=1;
else
dataused=0;
SetDataSize(BIGINT_ALLOCATE_BY);
data[0]=value;
}
BigInt(const unsigned __int32 value)
{
data=0;
dataallocated=0;
if (value)
dataused=1;
else
dataused=0;
SetDataSize(BIGINT_ALLOCATE_BY);
data[0]=value;
}
BigInt(const std::string s)
{
data=0;
dataallocated=0;
dataused=0;
SetDataSize(BIGINT_ALLOCATE_BY);
for (unsigned __int32 x=0; x<s.length(); ++x)
{
if (s[x]>='0' && s[x]<='9')
{
*this<<=4;
*this+=((int)s[x]-'0');
}
if (s[x]>='a' && s[x]<='f')
{
*this<<=4;
*this+=((int)s[x]-'a'+10);
}
if (s[x]>='A' && s[x]<='F')
{
*this<<=4;
*this+=((int)s[x]-'A'+10);
}
}
}
BigInt & operator += (const BIGINT_DATATYPE value)
{
++this->dataused;
if (this->dataused>this->dataallocated)
this->SetDataSize(this->dataused);
void *p=this->data;
__asm
{
mov eax,p
mov ebx,value
add [eax], ebx
jnc adddone
addloop:
add eax, 4
add [eax], 1
jc addloop
adddone:
}
if (!this->data[this->dataused-1])
--this->dataused;
return *this;
}
BigInt &operator += (const BigInt &value)
{
BIGINT_DATATYPE x=value.dataused;
this->dataused=x+1;
if (this->dataused>this->dataallocated)
this->SetDataSize(this->dataused);
void *p1=this->data;
void *p2=value.data;
__asm
{
mov eax,p1
mov ebx,p2
mov ecx,x
inc ecx
clc
addloop:
mov edx, [ebx]
adc [eax], edx
inc ebx
inc eax
inc ebx
inc eax
inc ebx
inc eax
inc ebx
inc eax
dec ecx
jnz addloop
jnc addshiftdone
addshiftloop:
add [eax], 1
inc eax
inc eax
inc eax
inc eax
jc addshiftloop
addshiftdone:
}
if (!this->data[x])
--this->dataused;
return *this;
}
BigInt & operator = (const __int32 value)
{
if (this->dataused>1)
ZeroUsed();
if (value)
this->dataused=1;
else
this->dataused=0;
this->data[0]=value;
return *this;
}
BigInt & operator = (const unsigned __int32 value)
{
if (this->dataused>1)
ZeroUsed();
if (value)
this->dataused=1;
else
this->dataused=0;
this->data[0]=value;
return *this;
}
BigInt & operator = (const BigInt &value)
{
this->Swap(BigInt(value));
return *this;
}
friend BigInt operator + (const BigInt &a, const BigInt &b)
{
return BigInt(a)+=b;
}
friend bool operator == (const BigInt &a, const int value)
{
int ad=a.dataused;
if (ad)
while (ad && !a.data[ad-1])
--ad;
if (ad>1)
return false;
if (!ad && !value)
return true;
return a.data[0]==value;
}
friend bool operator == (const BigInt &a, const BigInt &b)
{
int ad=a.dataused;
int bd=b.dataused;
if (ad)
while (ad && !a.data[ad-1])
--ad;
if (bd)
while (bd && !b.data[bd-1])
--bd;
if (ad!=bd)
return false;
for (int x=0; x<ad; ++x)
if (a.data[x]!=b.data[x])
return false;
return true;
}
friend bool operator != (const BigInt &a, const BigInt &b)
{
return !(a==b);
}
friend bool operator != (const BigInt &a, const int b)
{
return !(a==b);
}
friend bool operator > (const BigInt &a, const BigInt &b)
{
int ad=a.dataused;
int bd=b.dataused;
if (ad)
while (ad && !a.data[ad-1])
--ad;
if (bd)
while (bd && !b.data[bd-1])
--bd;
if (ad!=bd)
return ad>bd;
for (int x=ad-1; x>=0; --x)
if (a.data[x]!=b.data[x])
return a.data[x]>b.data[x];
return false;
}
friend bool operator < (const BigInt &a, const BigInt &b)
{
int ad=a.dataused;
int bd=b.dataused;
if (ad)
while (ad && !a.data[ad-1])
--ad;
if (bd)
while (bd && !b.data[bd-1])
--bd;
if (ad!=bd)
return ad<bd;
for (int x=ad-1; x>=0; --x)
if (a.data[x]!=b.data[x])
return a.data[x]<b.data[x];
return false;
}
friend bool operator >= (const BigInt &a, const BigInt &b)
{
int ad=a.dataused;
int bd=b.dataused;
if (ad)
while (ad && !a.data[ad-1])
--ad;
if (bd)
while (bd && !b.data[bd-1])
--bd;
if (ad!=bd)
return ad>bd;
for (int x=ad-1; x>=0; --x)
if (a.data[x]!=b.data[x])
return a.data[x]>b.data[x];
return true;
}
friend bool operator <= (const BigInt &a, const BigInt &b)
{
int ad=a.dataused;
int bd=b.dataused;
if (ad)
while (ad && !a.data[ad-1])
--ad;
if (bd)
while (bd && !b.data[bd-1])
--bd;
if (ad!=bd)
return ad<bd;
for (int x=ad-1; x>=0; --x)
if (a.data[x]!=b.data[x])
return a.data[x]<b.data[x];
return true;
}
std::string ToHex()
{
if (!this->dataused)
return std::string("0");
std::string str;
bool foundfirst=0;
for (int x = this->dataused-1; x>=0; --x)
{
int v;
for (int y=1; y<=BIGINT_BITS/4; ++y)
{
v = (this->data[x] & (0xF << (BIGINT_BITS-y*4))) >> (BIGINT_BITS-y*4);
if (foundfirst || v)
{
foundfirst=true;
if (v<10)
str+=((char)'0'+v);
else
str+=((char)'A'+v-10);
}
}
}
return str;
}
BigInt & operator ++ ()
{
for (int x=0; x<this->dataused; ++x)
if (++this->data[x])
return *this;
++this->dataused;
if (this->dataused>this->dataallocated)
this->SetDataSize(this->dataused);
this->data[this->dataused-1]=1;
return *this;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
BigInt a = 12472910;
BigInt b("123ABCDE098");
BigInt c=a+b;
std::cout << a.ToHex() << " + " << b.ToHex() << " = " << c.ToHex() << "\n";
_getch();
return 0;
}