"清理"双重值'不精确

时间:2014-07-16 01:46:36

标签: c#

我有一个程序将数据作为第三方API获取,但有时我得到的双重值表示为"不精确" (或太精确)的方式,例如。

0.3表示为0.2999999999999

0.04表示为0.03999999999999

这会导致问题,特别是当我想进行相等比较时。有没有办法清理"不精确"我收到它们的双值?

我能想到的是:

    public Form1()
    {
        InitializeComponent();

        double x = 0.2999999999999; //from third party API          
        x = cleanDouble(x); //x=0.3
    }

    private double cleanDouble(double input)
    {
        string s = input.ToString("0.##########");
        double.TryParse(s, out input);
        return input;
    }

有更有效的方法吗?将double转换为string并返回double对我来说似乎非常有效或优雅。

非常感谢。

P.S。出于我的应用目的,我将获得的值的精确度将超过0.00000001。

P.P.S。我事先不知道从第三方API获得什么价值。它可以是0.0004999999999,0.039999999999999,100.049999999999999等。

P.P.P.S。出于这个问题的目的,我需要使用double,而不是decimal。

3 个答案:

答案 0 :(得分:2)

您可以单独留下数字并编写自己的比较功能。类似的东西:

Bool Test = IsRoughlyEqual(.0001, .0002, .01);

public bool IsRoughlyEqual(double NumA, double NumB, double Tolerance)
{
    double Result = Math.Abs(NumA - NumB);

    if (Result > Tolerance)
        return false;
    else
        return true;
}

答案 1 :(得分:1)

我不确定您是如何提供这样的数据的,所以这可能适用也可能不适用,但Math.Round(double, int)是否安全?它并不完全优雅,它更像是对这个问题的创可贴。但如果真的没有办法清理你所吸引的东西,那就行了。

既然你说它不需要超过0.00000001的精确度,你就可以做到

Math.Round(value, 8);

答案 2 :(得分:0)

这比将双精度转换为字符串然后重新表示为双精度要快得多。

private double cleanDouble(double input)
{
    double ceil = Math.Ceil(input);
    if (ceil - input < 0.00000001)
        return ceil;

    double floor = Math.Floor(input);
    if (input - floor < 0.00000001)
        return floor;

    return input;
}

请记住,有些数字不能100%准确地用双精度表示,因此需要一些容差。