All pastes #587392 Raw Edit

Mine

public text v1 · immutable
#587392 ·published 2007-06-24 15:21 UTC
rendered paste body
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;
        }
}