Ejemplo n.º 1
0
        internal static BigInteger pow2ModPow(BigInteger _base, BigInteger exponent, int j)
        {
            // PRE: (base > 0), (exponent > 0) and (j > 0)
            BigInteger res         = BigInteger.ONE;
            BigInteger e           = exponent.copy();
            BigInteger baseMod2toN = _base.copy();
            BigInteger res2;

            /*
             * If 'base' is odd then it's coprime with 2^j and phi(2^j) = 2^(j-1);
             * so we can reduce reduce the exponent (mod 2^(j-1)).
             */
            if (_base.testBit(0))
            {
                inplaceModPow2(e, j - 1);
            }
            inplaceModPow2(baseMod2toN, j);

            for (int i = e.bitLength() - 1; i >= 0; i--)
            {
                res2 = res.copy();
                inplaceModPow2(res2, j);
                res = res.multiply(res2);
                if (BitLevel.testBit(e, i))
                {
                    res = res.multiply(baseMod2toN);
                    inplaceModPow2(res, j);
                }
            }
            inplaceModPow2(res, j);
            return(res);
        }
Ejemplo n.º 2
0
        public static BigInteger pow(BigInteger _base, int exponent)
        {
            // PRE: exp > 0
            BigInteger res = BigInteger.ONE;
            BigInteger acc = _base;

            for (; exponent > 1; exponent >>= 1)
            {
                if ((exponent & 1) != 0)
                {
                    // if odd, multiply one more time by acc
                    res = res.multiply(acc);
                }
                // acc = base^(2^i)
                //a limit where karatsuba performs a faster square than the square algorithm
                if (acc.numberLength == 1)
                {
                    acc = acc.multiply(acc); // square
                }
                else
                {
                    acc = new BigInteger(1, square(acc.digits, acc.numberLength, new int [acc.numberLength << 1]));
                }
            }
            // exponent == 1, multiply one more time
            res = res.multiply(acc);
            return(res);
        }
Ejemplo n.º 3
0
        public static BigInteger powerOf10(long exp)
        {
            // PRE: exp >= 0
            int intExp = (int)exp;

            // "SMALL POWERS"
            if (exp < bigTenPows.Length)
            {
                // The largest power that fit in 'long' type
                return(bigTenPows[intExp]);
            }
            else if (exp <= 50)
            {
                // To calculate:    10^exp
                return(BigInteger.TEN.pow(intExp));
            }
            else if (exp <= 1000)
            {
                // To calculate:    5^exp * 2^exp
                return(bigFivePows[1].pow(intExp).shiftLeft(intExp));
            }

            if (exp <= Int32.MaxValue)
            {
                // To calculate:    5^exp * 2^exp
                return(bigFivePows[1].pow(intExp).shiftLeft(intExp));
            }

            /*
             * "HUGE POWERS"
             *
             * This branch probably won't be executed since the power of ten is too
             * big.
             */
            // To calculate:    5^exp
            BigInteger powerOfFive = bigFivePows[1].pow(Int32.MaxValue);
            BigInteger res         = powerOfFive;
            long       longExp     = exp - Int32.MaxValue;

            intExp = (int)(exp % Int32.MaxValue);
            while (longExp > Int32.MaxValue)
            {
                res      = res.multiply(powerOfFive);
                longExp -= Int32.MaxValue;
            }
            res = res.multiply(bigFivePows[1].pow(intExp));
            // To calculate:    5^exp << exp
            res     = res.shiftLeft(Int32.MaxValue);
            longExp = exp - Int32.MaxValue;
            while (longExp > Int32.MaxValue)
            {
                res      = res.shiftLeft(Int32.MaxValue);
                longExp -= Int32.MaxValue;
            }
            res = res.shiftLeft(intExp);
            return(res);
        }
Ejemplo n.º 4
0
 public static BigInteger multiplyByFivePow(BigInteger val, int exp)
 {
     // PRE: exp >= 0
     if (exp < fivePows.Length)
     {
         return(multiplyByPositiveInt(val, fivePows[exp]));
     }
     else if (exp < bigFivePows.Length)
     {
         return(val.multiply(bigFivePows[exp]));
     }
     else    // Large powers of five
     {
         return(val.multiply(bigFivePows[1].pow(exp)));
     }
 }
Ejemplo n.º 5
0
 public static BigInteger multiplyByTenPow(BigInteger val, long exp)
 {
     // PRE: exp >= 0
     return((exp < tenPows.Length)
             ? multiplyByPositiveInt(val, tenPows[(int)exp])
             : val.multiply(powerOf10(exp)));
 }
Ejemplo n.º 6
0
        internal static BigInteger evenModPow(BigInteger _base, BigInteger exponent,
                                              BigInteger modulus)
        {
            // PRE: (base > 0), (exponent > 0), (modulus > 0) and (modulus even)
            // STEP 1: Obtain the factorization 'modulus'= q * 2^j.
            int        j = modulus.getLowestSetBit();
            BigInteger q = modulus.shiftRight(j);

            // STEP 2: Compute x1 := base^exponent (mod q).
            BigInteger x1 = oddModPow(_base, exponent, q);

            // STEP 3: Compute x2 := base^exponent (mod 2^j).
            BigInteger x2 = pow2ModPow(_base, exponent, j);

            // STEP 4: Compute q^(-1) (mod 2^j) and y := (x2-x1) * q^(-1) (mod 2^j)
            BigInteger qInv = modPow2Inverse(q, j);
            BigInteger y    = (x2.subtract(x1)).multiply(qInv);

            inplaceModPow2(y, j);
            if (y.sign < 0)
            {
                y = y.add(BigInteger.getPowerOfTwo(j));
            }
            // STEP 5: Compute and return: x1 + q * y
            return(x1.add(q.multiply(y)));
        }
Ejemplo n.º 7
0
        internal static BigInteger modPow2Inverse(BigInteger x, int n)
        {
            // PRE: (x > 0), (x is odd), and (n > 0)
            BigInteger y = new BigInteger(1, new int[1 << n]);

            y.numberLength = 1;
            y.digits[0]    = 1;
            y.sign         = 1;

            for (int i = 1; i < n; i++)
            {
                if (BitLevel.testBit(x.multiply(y), i))
                {
                    // Adding 2^i to y (setting the i-th bit)
                    y.digits[i >> 5] |= (1 << (i & 31));
                }
            }
            return(y);
        }
Ejemplo n.º 8
0
Archivo: Division.cs Proyecto: vic/ioke
        internal static BigInteger modPow2Inverse(BigInteger x, int n)
        {
            // PRE: (x > 0), (x is odd), and (n > 0)
            BigInteger y = new BigInteger(1, new int[1 << n]);
            y.numberLength = 1;
            y.digits[0] = 1;
            y.sign = 1;

            for (int i = 1; i < n; i++) {
                if (BitLevel.testBit(x.multiply(y), i)) {
                    // Adding 2^i to y (setting the i-th bit)
                    y.digits[i >> 5] |= (1 << (i & 31));
                }
            }
            return y;
        }
Ejemplo n.º 9
0
 public static BigInteger multiplyByFivePow(BigInteger val, int exp)
 {
     // PRE: exp >= 0
     if (exp < fivePows.Length) {
         return multiplyByPositiveInt(val, fivePows[exp]);
     } else if (exp < bigFivePows.Length) {
         return val.multiply(bigFivePows[exp]);
     } else {// Large powers of five
         return val.multiply(bigFivePows[1].pow(exp));
     }
 }
Ejemplo n.º 10
0
 public static BigInteger multiplyByTenPow(BigInteger val, long exp)
 {
     // PRE: exp >= 0
     return ((exp < tenPows.Length)
             ? multiplyByPositiveInt(val, tenPows[(int)exp])
             : val.multiply(powerOf10(exp)));
 }