/// <summary> /// Compute the square root of self to a given scale, Using Newton's /// algorithm. x >= 0. /// </summary> /// <param name="scale"> /// the desired <c>scale</c> of the result. (where the <c>scale</c> is /// the number of digits to the right of the decimal point. /// </param> /// <returns> /// the result value /// </returns> /// <exception cref="ArgumentException"> /// if <c>scale</c> is <= 0. /// </exception> /// <exception cref="ArgumentException"> /// if <c>self</c> is < 0. /// </exception> public static DecimalX Sqrt(this DecimalX x, int scale) { // Check that scale > 0. if (scale <= 0) { throw new ArgumentException(SqrtScaleInvalid); } // Check that x >= 0. if (x.Signum() < 0) { throw new ArgumentException(NegativeSquareRoot); } if (x.Signum() == 0) { return(new DecimalX(x.ToIntegerX(), -scale)); } // n = x*(10^(2*scale)) var n = x.MovePointRight(scale << 1).ToIntegerX(); // The first approximation is the upper half of n. var bits = (int)(n.BitLength() + 1) >> 1; var ix = n.RightShift(bits); IntegerX ixPrev = 0; // Loop until the approximations converge // (two successive approximations are equal after rounding). while (ix.CompareTo(ixPrev) != 0) { ixPrev = ix; // x = (x + n/x)/2 ix = ix.Add(n.Divide(ix)).RightShift(1); } return(new DecimalX(ix, -scale)); }