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

时间:2010-11-08 13:21:35

标签: c# math types double decimal

我想知道上述情况是否完全可能。例如:

Math.Sqrt(myVariableHere);

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

5 个答案:

答案 0 :(得分:51)

我不明白为什么这个问题的所有答案都是一样的。

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

// 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),循环重复次数少于三次。

如果您想了解更多信息,请阅读this (Hacker's Delight by Henry S. Warren, Jr.)

答案 1 :(得分:4)

在涉及decimal(货币等)的大多数情况下,取得根目录不是有用的;并且root将没有像decimal所期望的预期精度那样的东西。你当然可以通过强制转换强制它(假设我们没有处理decimal范围的极端):

decimal root = (decimal)Math.Sqrt((double)myVariableHere);

迫使你至少承认固有的四舍五入问题。

答案 2 :(得分:4)

我刚刚遇到过这个问题,我建议使用与SLenik提出的算法不同的算法。这基于Babylonian Method

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并返回,伴随着精度的降低。

答案 3 :(得分:-3)

简单:将decimal投射到double并调用该函数,获取结果并将其转换回decimal。这可能会比您自己制作的任何sqrt功能更快,并且可以节省很多精力。

答案 4 :(得分:-3)

Math.Sqrt((double)myVariableHere);

会给你一个双倍,即decimal myVariableHere的平方根。