我在想上述内容是否有可能实现。例如:
Math.Sqrt(myVariableHere);
当查看重载时,它需要一个双精度浮点数参数,因此我不确定是否有其他方法可以使用十进制数据类型来复制这个过程。
我不明白为什么那个问题的所有答案都是一样的。
有几种方法可以从一个数字中计算平方根。其中一种是由艾萨克·牛顿提出的。我只会写其中最简单的实现方式之一。我使用它来提高双精度浮点数的平方根精度。
// x - a number, from which we need to calculate the square root
// epsilon - an accuracy of calculation of the root from our number.
// The result of the calculations will differ from an actual value
// of the root on less than epslion.
public static decimal Sqrt(decimal x, decimal epsilon = 0.0M)
{
if (x < 0) throw new OverflowException("Cannot calculate square root from a negative number");
decimal current = (decimal)Math.Sqrt((double)x), previous;
do
{
previous = current;
if (previous == 0.0M) return 0;
current = (previous + x / previous) / 2;
}
while (Math.Abs(previous - current) > epsilon);
return current;
}
关于速度:在最坏的情况下(epsilon = 0且number为decimal.MaxValue),循环不到三次。
如果您想了解更多,请阅读这本书(《Hacker's Delight》by Henry S. Warren, Jr.)
我刚刚看到这个问题,我建议使用一种不同于SLenik提出的算法。这是基于巴比伦方法。
public static decimal Sqrt(decimal x, decimal? guess = null)
{
var ourGuess = guess.GetValueOrDefault(x / 2m);
var result = x / ourGuess;
var average = (ourGuess + result) / 2m;
if (average == ourGuess) // This checks for the maximum precision possible with a decimal.
return average;
else
return Sqrt(x, average);
}
这不需要使用现有的Sqrt
函数,从而避免了转换为double
并返回时伴随的精度损失。
decimal root = (decimal)Math.Sqrt((double)myVariableHere);
这将迫使您至少承认固有的四舍五入问题。
decimal
转换为 double
并调用函数,获取结果并将其转换回 decimal
。这可能比您自己编写任何 sqrt
函数都要快,并节省大量精力。Math.Sqrt((double)myVariableHere);
将返回一个双精度浮点数,它是您的decimal
myVariableHere
的平方根。
double
版本的Sqrt
仍然比任何其他方法都要快得多。 - Bobson