.NET的双precision问题问题、NET、precision

2023-09-02 21:08:21 作者:你的婚礼、我的葬礼

我有一个简单的C#功能:

I have a simple C# function:

public static double Floor(double value, double step)
{
    return Math.Floor(value / step) * step;
}

这比计算人数较多,低级或等于值,即多个步骤的。但它缺乏precision,如在下面的测试看出:

That calculates the higher number, lower than or equal to "value", that is multiple of "step". But it lacks precision, as seen in the following tests:

[TestMethod()]
public void FloorTest()
{
    int decimals = 6;
    double value = 5F;
    double step = 2F;
    double expected = 4F;
    double actual = Class.Floor(value, step);
    Assert.AreEqual(expected, actual);
    value = -11.5F;
    step = 1.1F;
    expected = -12.1F;
    actual = Class.Floor(value, step);
    Assert.AreEqual(Math.Round(expected, decimals),Math.Round(actual, decimals));
    Assert.AreEqual(expected, actual);
}

第一和第二断言都OK,但是第三个失败,因为结果仅相当于直到第6位小数。这是为什么?有什么办法来纠正呢?

The first and second asserts are ok, but the third fails, because the result is only equal until the 6th decimal place. Why is that? Is there any way to correct this?

更新如果我调试测试,我看到的值相等,直到第8位小数,而不是6日,也许是因为Math.Round介绍了一些IM precision。

Update If I debug the test I see that the values are equal until the 8th decimal place instead of the 6th, maybe because Math.Round introduces some imprecision.

注意在我的测试code我写了F后缀(显式的浮点常数),我的意思是D(双),所以如果我改变,我可以有更多的precision。

Note In my test code I wrote the "F" suffix (explicit float constant) where I meant "D" (double), so if I change that I can have more precision.

推荐答案

如果您省略所有在F后缀(即 -12.1 而不是 - 12.1F ),您将得到平等几个数字了。你常数(尤其是预期值),现在漂浮,因为 F 的。如果你是这样做的目的,那么请你解释一下。

If you omit all the F postfixes (ie -12.1 instead of -12.1F) you will get equality to a few digits more. Your constants (and especially the expected values) are now floats because of the F. If you are doing that on purpose then please explain.

但对于其余的我同意在平等比较双重或浮点值的其他的答案,它只是不可靠的。

But for the rest i concur with the other answers on comparing double or float values for equality, it's just not reliable.