在 C# 中对十进制数据类型执行数学运算?

问题描述 投票:0回答:5

我想知道上述是否可能。例如:

Math.Sqrt(myVariableHere);

在查看重载时,它需要一个双参数,所以我不确定是否有另一种方法可以用十进制数据类型复制它。

c# math types double decimal
5个回答
64
投票

有多种方法可以计算数字的平方根。其中之一是艾萨克·牛顿提出的。我只会编写此方法的最简单的实现之一。我用它来提高双精度平方根的准确性。

// 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 且数字为十进制。MaxValue)循环重复次数少于 3 次。

如果您想了解更多信息,请阅读 此(Henry S. Warren, Jr. 的《黑客的喜悦》)


7
投票
我刚刚遇到这个问题,我建议采用一种与 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
 并返回,从而避免随之而来的精度损失。


5
投票
在大多数涉及

decimal

(货币等)的情况下,扎根并不“有用”;并且根不会有像您期望的 
decimal 那样的预期精度。您当然可以通过强制转换来强制它(假设我们不处理 decimal
 范围的极端):
decimal root = (decimal)Math.Sqrt((double)myVariableHere);

这迫使您至少承认固有的舍入问题。
    

简单:将

-3
投票
转换为

double

 并调用该函数,获取结果并将其转换回 
decimal
。这可能比您自己制作的任何 
sqrt
 功能都要快,并且节省大量精力。

Math.Sqrt((double)myVariableHere);

-4
投票
将返回一个双倍,即您的
decimal

myVariableHere

 的平方根。

© www.soinside.com 2019 - 2024. All rights reserved.