import 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; } }