Consider using Math.Sqrt(double) to produce an initial estimate of the square root. This improved performance 5x on my machine.
/// <summary>
/// Returns the square root of a given number.
/// </summary>
/// <param name="s">A non-negative number.</param>
/// <remarks>
/// Uses an implementation of the "Babylonian Method".
/// See http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
/// </remarks>
public static decimal Sqrt(decimal s)
{
if (s < 0)
throw new ArgumentException("Square root not defined for Decimal data type when less than zero!", "s");
// Prevent divide-by-zero errors below. Dividing either
// of the numbers below will yield a recurring 0 value
// for halfS eventually converging on zero.
if (s == 0 || s == SmallestNonZeroDec) return 0;
var x = (decimal)Math.Sqrt((double)s);
var halfS = s / 2m;
var lastX = -1m;
decimal nextX;
while (true)
{
nextX = x / 2m + halfS / x;
// The next check effectively sees if we've ran out of
// precision for our data type.
if (nextX == x || nextX == lastX) break;
lastX = x;
x = nextX;
}
return nextX;
}
That's a good point. And there may be some other ways to perform a faster starting approximation or even a better overall algorithm that converges more quickly. I'll look into it.
Consider using Math.Sqrt(double) to produce an initial estimate of the square root. This improved performance 5x on my machine.