if (exponent <= 0) { if (exponent == 0) return ONE; else throw new ArithmeticException("negative exponent"); }
if (isOne()) return this; if (isMinusOne()) return y.isOdd () ? this : ONE; if (y.words == null && y.ival >= 0) return pow(y.ival);
  public BigInteger pow(int exponent)  {    if (exponent <= 0)      {	if (exponent == 0)	  return ONE;	else	  throw new ArithmeticException("negative exponent");      }    if (isZero())      return this;    int plen = words == null ? 1 : ival;  // Length of pow2.    int blen = ((bitLength() * exponent) >> 5) + 2 * plen;    boolean negative = isNegative() && (exponent & 1) != 0;    int[] pow2 = new int [blen];    int[] rwords = new int [blen];    int[] work = new int [blen];    getAbsolute(pow2);	// pow2 = abs(this);    int rlen = 1;    rwords[0] = 1; // rwords = 1;    for (;;)  // for (i = 0;  ; i++)      {	// pow2 == this**(2**i)	// prod = this**(sum(j=0..i-1, (exponent>>j)&1))	if ((exponent & 1) != 0)	  { // r *= pow2	    MPN.mul(work, pow2, plen, rwords, rlen);	    int[] temp = work;  work = rwords;  rwords = temp;	    rlen += plen;	    while (rwords[rlen - 1] == 0)  rlen--;	  }	exponent >>= 1;	if (exponent == 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 BigInteger.make(rwords, rlen);  }