示例#1
0
        //
        // Subtracts b from a and outputs the result in c.
        //

        internal static void Subtract(BigInt a, BigInt b, ref BigInt c)
        {
            byte borrow = 0;
            int  diff   = 0;

            if (a < b)
            {
                Subtract(b, a, ref c);
                Negate(ref c);
                return;
            }

            int index   = 0;
            int size    = a.Size;
            int newSize = 0;

            for (index = 0; index < size; index++)
            {
                diff   = a.GetDigit(index) - b.GetDigit(index) - borrow;
                borrow = 0;
                if (diff < 0)
                {
                    diff  += m_base;
                    borrow = 1;
                }
                c.SetDigit(index, (byte)(diff & 0xFF), ref newSize);
            }

            c.Size = newSize;
        }
 private static void Multiply(BigInt a, int b, ref BigInt c)
 {
     if (b == 0)
     {
         c.Clear();
     }
     else
     {
         int num  = 0;
         int num2 = 0;
         int size = a.Size;
         int num4 = 0;
         for (int i = 0; i < size; i++)
         {
             num2 = (b * a.GetDigit(i)) + num;
             num  = num2 / 0x100;
             c.SetDigit(i, (byte)(num2 % 0x100), ref num4);
         }
         if (num != 0)
         {
             byte[] bytes = BitConverter.GetBytes(num);
             for (int j = 0; j < bytes.Length; j++)
             {
                 c.SetDigit(size + j, bytes[j], ref num4);
             }
         }
         c.Size = num4;
     }
 }
        internal static void Subtract(BigInt a, BigInt b, ref BigInt c)
        {
            byte num  = 0;
            int  num2 = 0;

            if (a < b)
            {
                Subtract(b, a, ref c);
                Negate(ref c);
            }
            else
            {
                int index = 0;
                int size  = a.Size;
                int num5  = 0;
                for (index = 0; index < size; index++)
                {
                    num2 = (a.GetDigit(index) - b.GetDigit(index)) - num;
                    num  = 0;
                    if (num2 < 0)
                    {
                        num2 += 0x100;
                        num   = 1;
                    }
                    c.SetDigit(index, (byte)(num2 & 0xff), ref num5);
                }
                c.Size = num5;
            }
        }
示例#4
0
        private static void Multiply(BigInt a, int b, ref BigInt c)
        {
            if (b == 0)
            {
                c.Clear();
                return;
            }

            int carry = 0, product = 0;
            int size    = a.Size;
            int newSize = 0;

            for (int index = 0; index < size; index++)
            {
                product = b * a.GetDigit(index) + carry;
                carry   = product / m_base;
                c.SetDigit(index, (byte)(product % m_base), ref newSize);
            }

            if (carry != 0)
            {
                byte[] bytes = BitConverter.GetBytes(carry);
                for (int index = 0; index < bytes.Length; index++)
                {
                    c.SetDigit(size + index, bytes[index], ref newSize);
                }
            }

            c.Size = newSize;
        }
 internal static void Divide(BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder)
 {
     if (numerator < denominator)
     {
         quotient.Clear();
         remainder.CopyFrom(numerator);
     }
     else if (numerator == denominator)
     {
         quotient.Clear();
         quotient.SetDigit(0, 1);
         remainder.Clear();
     }
     else
     {
         BigInt a = new BigInt();
         a.CopyFrom(numerator);
         BigInt num2 = new BigInt();
         num2.CopyFrom(denominator);
         uint num3 = 0;
         while (num2.Size < a.Size)
         {
             num2.Multiply(0x100);
             num3++;
         }
         if (num2 > a)
         {
             num2.Divide(0x100);
             num3--;
         }
         int    num4  = 0;
         int    digit = 0;
         int    b     = 0;
         BigInt c     = new BigInt();
         quotient.Clear();
         for (int i = 0; i <= num3; i++)
         {
             num4  = (a.Size == num2.Size) ? a.GetDigit(a.Size - 1) : ((0x100 * a.GetDigit(a.Size - 1)) + a.GetDigit(a.Size - 2));
             digit = num2.GetDigit(num2.Size - 1);
             b     = num4 / digit;
             if (b >= 0x100)
             {
                 b = 0xff;
             }
             Multiply(num2, b, ref c);
             while (c > a)
             {
                 b--;
                 Multiply(num2, b, ref c);
             }
             quotient.Multiply(0x100);
             Add(quotient, (byte)b, ref quotient);
             Subtract(a, c, ref a);
             num2.Divide(0x100);
         }
         remainder.CopyFrom(a);
     }
 }
示例#6
0
        //
        // Negates a BigInt value. Each byte is complemented, then we add 1 to it.
        //

        internal static void Negate(ref BigInt a)
        {
            int newSize = 0;

            for (int index = 0; index < m_maxbytes; index++)
            {
                a.SetDigit(index, (byte)(~a.GetDigit(index) & 0xFF), ref newSize);
            }
            for (int index = 0; index < m_maxbytes; index++)
            {
                a.SetDigit(index, (byte)(a.GetDigit(index) + 1), ref newSize);
                if ((a.GetDigit(index) & 0xFF) != 0)
                {
                    break;
                }
                a.SetDigit(index, (byte)(a.GetDigit(index) & 0xFF), ref newSize);
            }
            a.Size = newSize;
        }
        internal static void Negate(ref BigInt a)
        {
            int size = 0;

            for (int i = 0; i < 0x80; i++)
            {
                a.SetDigit(i, (byte)(~a.GetDigit(i) & 0xff), ref size);
            }
            for (int j = 0; j < 0x80; j++)
            {
                a.SetDigit(j, (byte)(a.GetDigit(j) + 1), ref size);
                if ((a.GetDigit(j) & 0xff) != 0)
                {
                    break;
                }
                a.SetDigit(j, (byte)(a.GetDigit(j) & 0xff), ref size);
            }
            a.Size = size;
        }
 internal static void Add(BigInt a, byte b, ref BigInt c)
 {
     byte digit = b;
     int num2 = 0;
     int size = a.Size;
     int num4 = 0;
     for (int i = 0; i < size; i++)
     {
         num2 = a.GetDigit(i) + digit;
         c.SetDigit(i, (byte) (num2 & 0xff), ref num4);
         digit = (byte) ((num2 >> 8) & 0xff);
     }
     if (digit != 0)
     {
         c.SetDigit(a.Size, digit, ref num4);
     }
     c.Size = num4;
 }
        internal static void Add(BigInt a, byte b, ref BigInt c)
        {
            byte digit = b;
            int  num2  = 0;
            int  size  = a.Size;
            int  num4  = 0;

            for (int i = 0; i < size; i++)
            {
                num2 = a.GetDigit(i) + digit;
                c.SetDigit(i, (byte)(num2 & 0xff), ref num4);
                digit = (byte)((num2 >> 8) & 0xff);
            }
            if (digit != 0)
            {
                c.SetDigit(a.Size, digit, ref num4);
            }
            c.Size = num4;
        }
示例#10
0
        //
        // Adds a and b and outputs the result in c.
        //

        internal static void Add(BigInt a, byte b, ref BigInt c)
        {
            byte carry = b;
            int  sum   = 0;

            int size    = a.Size;
            int newSize = 0;

            for (int index = 0; index < size; index++)
            {
                sum = a.GetDigit(index) + carry;
                c.SetDigit(index, (byte)(sum & 0xFF), ref newSize);
                carry = (byte)((sum >> 8) & 0xFF);
            }

            if (carry != 0)
            {
                c.SetDigit(a.Size, carry, ref newSize);
            }

            c.Size = newSize;
        }
示例#11
0
        //
        // Integer division of one BigInt by another.
        //

        internal static void Divide (BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder) {
            // Avoid extra computations in special cases.

            if (numerator < denominator) {
                quotient.Clear();
                remainder.CopyFrom(numerator);
                return;
            }
    
            if (numerator == denominator) {
                quotient.Clear(); quotient.SetDigit(0, 1); 
                remainder.Clear();
                return;
            }

            BigInt dividend = new BigInt();
            dividend.CopyFrom(numerator);
            BigInt divisor = new BigInt();
            divisor.CopyFrom(denominator);

            uint zeroCount = 0;
            // We pad the divisor with zeros until its size equals that of the dividend.
            while (divisor.Size < dividend.Size) {
                divisor.Multiply(m_base);
                zeroCount++; 
            }

            if (divisor > dividend) {
                divisor.Divide(m_base);
                zeroCount--;
            }

            // Use school division techniques, make a guess for how many times
            // divisor goes into dividend, making adjustment if necessary.
            int a = 0;
            int b = 0;
            int c = 0;

            BigInt hold = new BigInt();
            quotient.Clear();
            for (int index = 0; index <= zeroCount; index++) {
                a = dividend.Size == divisor.Size ? dividend.GetDigit(dividend.Size - 1) :
                                                    m_base * dividend.GetDigit(dividend.Size - 1) + dividend.GetDigit(dividend.Size - 2);
                b = divisor.GetDigit(divisor.Size - 1);
                c = a / b;

                if (c >= m_base) 
                    c = 0xFF;

                Multiply(divisor, c, ref hold);
                while (hold > dividend) {
                    c--;
                    Multiply(divisor, c, ref hold);
                }

                quotient.Multiply(m_base);
                Add(quotient, (byte) c, ref quotient);
                Subtract(dividend, hold, ref dividend);
                divisor.Divide(m_base);
            }
            remainder.CopyFrom(dividend);
        }
示例#12
0
        //
        // Subtracts b from a and outputs the result in c.
        //

        internal static void Subtract (BigInt a, BigInt b, ref BigInt c) {
            byte borrow = 0;
            int diff = 0;

            if (a < b) {
                Subtract(b, a, ref c);
                Negate(ref c);
                return;
            }

            int index = 0;
            int size = a.Size;
            int newSize = 0;
            for (index = 0; index < size; index++) {
                diff = a.GetDigit(index) - b.GetDigit(index) - borrow;
                borrow = 0;
                if (diff < 0) {
                    diff += m_base;
                    borrow = 1;
                }
                c.SetDigit(index, (byte) (diff & 0xFF), ref newSize);
            }

            c.Size = newSize;
        }
示例#13
0
        private static void Multiply (BigInt a, int b, ref BigInt c) {
            if (b == 0) {
                c.Clear();
                return;
            }
                
            int carry = 0, product = 0;
            int size = a.Size;
            int newSize = 0;
            for (int index = 0; index < size; index++) {
                product = b * a.GetDigit(index) + carry;
                carry = product / m_base;
                c.SetDigit(index, (byte) (product % m_base), ref newSize);
            }

            if (carry != 0) {
                byte[] bytes = BitConverter.GetBytes(carry);
                for (int index = 0; index < bytes.Length; index++) {
                    c.SetDigit(size + index, bytes[index], ref newSize);
                }
            }

            c.Size = newSize;
        }
示例#14
0
        //
        // Negates a BigInt value. Each byte is complemented, then we add 1 to it.
        //

        internal static void Negate (ref BigInt a) {
            int newSize = 0;
            for (int index = 0; index < m_maxbytes; index++) {
                a.SetDigit(index, (byte) (~a.GetDigit(index) & 0xFF), ref newSize);
            }
            for (int index = 0; index < m_maxbytes; index++) {
                a.SetDigit(index, (byte) (a.GetDigit(index) + 1), ref newSize);
                if ((a.GetDigit(index) & 0xFF) != 0) break;
                a.SetDigit(index, (byte) (a.GetDigit(index) & 0xFF), ref newSize);
            }            
            a.Size = newSize;
        }
示例#15
0
        //
        // Adds a and b and outputs the result in c.
        //

        internal static void Add (BigInt a, byte b, ref BigInt c) {
            byte carry = b;
            int sum = 0;

            int size = a.Size;
            int newSize = 0;
            for (int index = 0; index < size; index++) {
                sum = a.GetDigit(index) + carry;
                c.SetDigit(index, (byte) (sum & 0xFF), ref newSize);
                carry = (byte) ((sum >> 8) & 0xFF);
            }

            if (carry != 0)
                c.SetDigit(a.Size, carry, ref newSize);

            c.Size = newSize;
        }
 internal static void Divide(BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder)
 {
     if (numerator < denominator)
     {
         quotient.Clear();
         remainder.CopyFrom(numerator);
     }
     else if (numerator == denominator)
     {
         quotient.Clear();
         quotient.SetDigit(0, 1);
         remainder.Clear();
     }
     else
     {
         BigInt a = new BigInt();
         a.CopyFrom(numerator);
         BigInt num2 = new BigInt();
         num2.CopyFrom(denominator);
         uint num3 = 0;
         while (num2.Size < a.Size)
         {
             num2.Multiply(0x100);
             num3++;
         }
         if (num2 > a)
         {
             num2.Divide(0x100);
             num3--;
         }
         int num4 = 0;
         int digit = 0;
         int b = 0;
         BigInt c = new BigInt();
         quotient.Clear();
         for (int i = 0; i <= num3; i++)
         {
             num4 = (a.Size == num2.Size) ? a.GetDigit(a.Size - 1) : ((0x100 * a.GetDigit(a.Size - 1)) + a.GetDigit(a.Size - 2));
             digit = num2.GetDigit(num2.Size - 1);
             b = num4 / digit;
             if (b >= 0x100)
             {
                 b = 0xff;
             }
             Multiply(num2, b, ref c);
             while (c > a)
             {
                 b--;
                 Multiply(num2, b, ref c);
             }
             quotient.Multiply(0x100);
             Add(quotient, (byte) b, ref quotient);
             Subtract(a, c, ref a);
             num2.Divide(0x100);
         }
         remainder.CopyFrom(a);
     }
 }
 internal static void Subtract(BigInt a, BigInt b, ref BigInt c)
 {
     byte num = 0;
     int num2 = 0;
     if (a < b)
     {
         Subtract(b, a, ref c);
         Negate(ref c);
     }
     else
     {
         int index = 0;
         int size = a.Size;
         int num5 = 0;
         for (index = 0; index < size; index++)
         {
             num2 = (a.GetDigit(index) - b.GetDigit(index)) - num;
             num = 0;
             if (num2 < 0)
             {
                 num2 += 0x100;
                 num = 1;
             }
             c.SetDigit(index, (byte) (num2 & 0xff), ref num5);
         }
         c.Size = num5;
     }
 }
 internal static void Negate(ref BigInt a)
 {
     int size = 0;
     for (int i = 0; i < 0x80; i++)
     {
         a.SetDigit(i, (byte) (~a.GetDigit(i) & 0xff), ref size);
     }
     for (int j = 0; j < 0x80; j++)
     {
         a.SetDigit(j, (byte) (a.GetDigit(j) + 1), ref size);
         if ((a.GetDigit(j) & 0xff) != 0)
         {
             break;
         }
         a.SetDigit(j, (byte) (a.GetDigit(j) & 0xff), ref size);
     }
     a.Size = size;
 }
示例#19
0
        //
        // Integer division of one BigInt by another.
        //

        internal static void Divide(BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder)
        {
            // Avoid extra computations in special cases.

            if (numerator < denominator)
            {
                quotient.Clear();
                remainder.CopyFrom(numerator);
                return;
            }

            if (numerator == denominator)
            {
                quotient.Clear(); quotient.SetDigit(0, 1);
                remainder.Clear();
                return;
            }

            BigInt dividend = new BigInt();

            dividend.CopyFrom(numerator);
            BigInt divisor = new BigInt();

            divisor.CopyFrom(denominator);

            uint zeroCount = 0;

            // We pad the divisor with zeros until its size equals that of the dividend.
            while (divisor.Size < dividend.Size)
            {
                divisor.Multiply(m_base);
                zeroCount++;
            }

            if (divisor > dividend)
            {
                divisor.Divide(m_base);
                zeroCount--;
            }

            // Use school division techniques, make a guess for how many times
            // divisor goes into dividend, making adjustment if necessary.
            int a = 0;
            int b = 0;
            int c = 0;

            BigInt hold = new BigInt();

            quotient.Clear();
            for (int index = 0; index <= zeroCount; index++)
            {
                a = dividend.Size == divisor.Size ? dividend.GetDigit(dividend.Size - 1) :
                    m_base *dividend.GetDigit(dividend.Size - 1) + dividend.GetDigit(dividend.Size - 2);

                b = divisor.GetDigit(divisor.Size - 1);
                c = a / b;

                if (c >= m_base)
                {
                    c = 0xFF;
                }

                Multiply(divisor, c, ref hold);
                while (hold > dividend)
                {
                    c--;
                    Multiply(divisor, c, ref hold);
                }

                quotient.Multiply(m_base);
                Add(quotient, (byte)c, ref quotient);
                Subtract(dividend, hold, ref dividend);
                divisor.Divide(m_base);
            }
            remainder.CopyFrom(dividend);
        }
 private static void Multiply(BigInt a, int b, ref BigInt c)
 {
     if (b == 0)
     {
         c.Clear();
     }
     else
     {
         int num = 0;
         int num2 = 0;
         int size = a.Size;
         int num4 = 0;
         for (int i = 0; i < size; i++)
         {
             num2 = (b * a.GetDigit(i)) + num;
             num = num2 / 0x100;
             c.SetDigit(i, (byte) (num2 % 0x100), ref num4);
         }
         if (num != 0)
         {
             byte[] bytes = BitConverter.GetBytes(num);
             for (int j = 0; j < bytes.Length; j++)
             {
                 c.SetDigit(size + j, bytes[j], ref num4);
             }
         }
         c.Size = num4;
     }
 }