public BigDecimal pow(BigDecimal rhs,MathContext set) { int n; BigDecimal lhs; int reqdig; int workdigits=0; int L=0; MathContext workset; BigDecimal res; bool seenbit; int i=0; if (set.lostDigits) checkdigits(rhs,set.digits); n=rhs.intcheck(MinArg,MaxArg); // check RHS by the rules lhs=this; // clarified name reqdig=set.digits; // local copy (heavily used) if (reqdig==0) { if (rhs.ind==isneg) throw new System.ArithmeticException("Negative power:"+" "+rhs.ToString()); workdigits=0; } else {/* non-0 digits */ if ((rhs.mant.Length+rhs.exp)>reqdig) throw new System.ArithmeticException("Too many digits:"+" "+rhs.ToString()); /* Round the lhs to DIGITS if need be */ if (lhs.mant.Length>reqdig) lhs=clone(lhs).round(set); /* L for precision calculation [see ANSI X3.274-1996] */ L=rhs.mant.Length+rhs.exp; // length without decimal zeros/exp workdigits=(reqdig+L)+1; // calculate the working DIGITS } workset=new MathContext(workdigits,set.form,false,set.roundingMode); res=ONE; // accumulator if (n==0) return res; // x**0 == 1 if (n<0) n=(int)-n; // [rhs.ind records the sign] seenbit=false; // set once we've seen a 1-bit for(i=1;;i++){ // for each bit [top bit ignored] n=n+n; // shift left 1 bit if (n<0) { // top bit is set seenbit=true; // OK, we're off res=res.multiply(lhs,workset); // acc=acc*x } if (i==31) break; // that was the last bit if ((!seenbit)) continue; // we don't have to square 1 res=res.multiply(res,workset); // acc=acc*acc [square] } if (rhs.ind<0) // was a **-n [hence digits>0] res=ONE.divide(res,workset); // .. so acc=1/acc return res.finish(set,true); // round and strip [original digits] }