rendered paste bodyimport tango.io.Stdout;
import tango.stdc.stdio;
void main(char[][] args)
{
BigNumber test = new BigNumber([0x000Fu,0x0FFFu,0x0FFFu,0xFFFFu],128,0u);
foreach(key,val;test.segments)
{
printf("[%d] : %X\n",key,val);
}
BigNumber test2 = new BigNumber([0xFFFFu,0xFFF0u,0xFF00u,0xF000u],128,0u);
foreach(key,val;test2.segments)
{
printf("[%d] : %X\n",key,val);
}
test = test ^ test2;
foreach(key,val;test.segments)
{
printf("[%d] : %X\n",key,val);
}
}
static final class BigNumber
{
uint[] segments = void;
uint bitCount = void;
ubyte bitsOff = void;
ubyte flags = 0;
/*
flags
[128] - isNegative
[64] - isCopy
[32] - carryBit
[16] -
[8] -
[4] -
[2] -
[1] - isZero
*/
this(uint[] source,uint bits,ubyte properties)
{
this.segments = source.reverse;
this.bitCount = bits;
this.bitsOff = (bits % 32);
this.flags = properties;
}
void setSize(int numberOfBits)
{
segments.length = (numberOfBits + 31) >> 5;
bitCount = numberOfBits;
}
BigNumber opNeg()
{
// Flip the negative flag and make sure the copy flag is on
return new BigNumber(segments,bitCount,(flags^128)|64);
}
BigNumber opPos()
{
// Make sure everything but the isNegative is the same
return new BigNumber(segments,bitCount,(flags&127)|64);
}
BigNumber opPostInc()
{
for(uint i = 0;i < segments.length;i++)
{
if(segments[i] == 0xFFFFFFFF) segments[i] = 0;
else segments[i]++;
}
return this;
}
BigNumber opPostDec()
{
for(uint i = 0;i < segments.length;i++)
{
if(segments[i] == 0x00000000) segments[i] = 0xFFFFFFFF;
else segments[i]--;
}
return this;
}
BigNumber opCom()
{
for(uint i = 0;i < segments.length;i++)
{
segments[i] ^= 0xFFFFFFFF;
}
return this;
}
uint[] opCast()
{
return segments.dup;
}
BigNumber opAnd(BigNumber other)
{
uint lengthOf = (this.segments.length > other.segments.length ? this.segments.length : other.segments.length)-1;
ubyte bitsOff = this.bitsOff > other.bitsOff ? this.bitsOff : other.bitsOff;
for(uint i = 0;i < lengthOf ;i++)
{
this.segments[i] &= other.segments[i];
}
this.segments[lengthOf] &= other.segments[lengthOf]&(0xFFFFFFFF>>>bitsOff);
return this;
}
BigNumber opOr(BigNumber other)
{
uint lengthOf = (this.segments.length > other.segments.length ? this.segments.length : other.segments.length)-1;
ubyte bitsOff = this.bitsOff > other.bitsOff ? this.bitsOff : other.bitsOff;
for(uint i = 0;i < lengthOf ;i++)
{
this.segments[i] |= other.segments[i];
}
this.segments[lengthOf] |= other.segments[lengthOf]&(0xFFFFFFFF>>>bitsOff);
return this;
}
BigNumber opXor(BigNumber other)
{
uint lengthOf = (this.segments.length > other.segments.length ? this.segments.length : other.segments.length)-1;
ubyte bitsOff = this.bitsOff > other.bitsOff ? this.bitsOff : other.bitsOff;
for(uint i = 0;i < lengthOf ;i++)
{
this.segments[i] ^= other.segments[i];
}
this.segments[lengthOf] ^= other.segments[lengthOf]&(0xFFFFFFFF>>>bitsOff);
return this;
}
BigNumber opAdd(BigNumber other)
{
uint lengthOf = (this.segments.length > other.segments.length ? this.segments.length : other.segments.length)-1;
ubyte bitsOff = this.bitsOff > other.bitsOff ? this.bitsOff : other.bitsOff;
ubyte carry = 0;
for(uint i = 0;;i++)
{
carry += other.segments[i];
this.segments[i] += carry;
if(this.segments[i] < carry)
carry = 1;
else
carry = 0;
if(i >= lengthOf)
break;
}
carry += (other.segments[lengthOf]&(0xFFFFFFFF>>>bitsOff));
this.segments[lengthOf] += carry;
if(this.segments[lengthOf] < carry)
if(segments.length > lengthOf)
segments[lengthOf+1]++;
else
flags |= 32;
return this;
}
}