예제 #1
0
파일: IntNum.cs 프로젝트: vic/ioke
 /** Calculate the integral power of an IntNum.
  * @param x the value (base) to exponentiate
  * @param y the exponent (must be non-negative)
  */
 public static IntNum power(IntNum x, int y)
 {
     if (y <= 0)
         {
             if (y == 0)
                 return one ();
             else
                 throw new Exception ("negative exponent");
         }
     if (x.isZero ())
         return x;
     int plen = x.words == null ? 1 : x.ival;  // Length of pow2.
     int blen = ((x.intLength () * y) >> 5) + 2 * plen;
     bool negative = x.isNegative () && (y & 1) != 0;
     int[] pow2 = new int [blen];
     int[] rwords = new int [blen];
     int[] work = new int [blen];
     x.getAbsolute (pow2);	// pow2 = abs(x);
     int rlen = 1;
     rwords[0] = 1; // rwords = 1;
     for (;;)  // for (i = 0;  ; i++)
         {
             // pow2 == x**(2**i)
             // prod = x**(sum(j=0..i-1, (y>>j)&1))
             if ((y & 1) != 0)
                 { // r *= pow2
                     MPN.mul (work, pow2, plen, rwords, rlen);
                     int[] tempx = work;  work = rwords;  rwords = tempx;
                     rlen += plen;
                     while (rwords[rlen-1] == 0)  rlen--;
                 }
             y >>= 1;
             if (y == 0)
                 break;
             // pow2 *= pow2;
             MPN.mul (work, pow2, plen, pow2, plen);
             int[] temp = work;  work = pow2;  pow2 = temp;  // swap to avoid a copy
             plen *= 2;
             while (pow2[plen-1] == 0)  plen--;
         }
     if (rwords[rlen-1] < 0)
         rlen++;
     if (negative)
         negate (rwords, rwords, rlen);
     return IntNum.make (rwords, rlen);
 }