static void Sqrt(BigNumber src, BigNumber dst, int places) { int ii, nexp, tolerance, dplaces; bool bflag; if (src.signum <= 0) { if (src.signum == -1) { throw new BigNumberException("'Sqrt',Invalid Argument"); } } BigNumber last_x = new BigNumber(); BigNumber guess = new BigNumber(); BigNumber tmpN = new BigNumber(); BigNumber tmp7 = new BigNumber(); BigNumber tmp8 = new BigNumber(); BigNumber tmp9 = new BigNumber(); BigNumber.Copy(src, tmpN); nexp = src.exponent / 2; tmpN.exponent -= 2 * nexp; BigNumber.SQrtGuess(tmpN, guess); tolerance = places + 4; dplaces = places + 16; bflag = false; BigNumber.Neg(BigNumber.Ten, last_x); ii = 0; while (true) { BigNumber.Mul(tmpN, guess, tmp9); BigNumber.Mul(tmp9, guess, tmp8); BigNumber.Round(tmp8, tmp7, dplaces); BigNumber.Sub(BigNumber.Three, tmp7, tmp9); BigNumber.Mul(tmp9, guess, tmp8); BigNumber.Mul(tmp8, BigNumber.BN_OneHalf, tmp9); if (bflag) { break; } BigNumber.Round(tmp9, guess, dplaces); if (ii != 0) { BigNumber.Sub(guess, last_x, tmp7); if (tmp7.signum == 0) { break; } /* * if we are within a factor of 4 on the error term, * we will be accurate enough after the *next* iteration * is complete. (note that the sign of the exponent on * the error term will be a negative number). */ if ((-4 * tmp7.exponent) > tolerance) { bflag = true; } } BigNumber.Copy(guess, last_x); ii++; } BigNumber.Mul(tmp9, tmpN, tmp8); BigNumber.Round(tmp8, dst, places); dst.exponent += nexp; }