3

正如问题所暗示的那样(更多的声明很抱歉)我在 C# 中使用 math.truncate 时遇到问题。我要做的是说当一个数字的小数除以 50 等于 0.4 时,这样做:

double temp2 = 170;    
temp2 = temp2 / 50;   //this equals 3.4
temp2 -= Math.Truncate(temp2);
if (temp2 == 0.4)
{
    Console.WriteLine("Hello");
}

但是,当我尝试这样做时,它对我不起作用,我不确定为什么它不起作用,我能否让某人对此有所了解并让我朝着正确的方向前进?

4

2 回答 2

4

single并且double是二进制浮点类型。这意味着它们不能准确地表示许多十进制值(例如 0.4)。这可能会导致细微的舍入错误,因此比较double逻辑上应该表示相同值的两个值可能会导致意外结果。

这可以使用以下DoubleToInt64Bits方法进行经验验证:

BitConverter.DoubleToInt64Bits(temp2); // 4600877379321698712
BitConverter.DoubleToInt64Bits(0.4);   // 4600877379321698714

将其更改为decimal,您将获得预期的结果:

decimal temp2 = 170;    
temp2 = temp2 / 50;   //this equals 3.4
temp2 -= Math.Truncate(temp2);
if (temp2 == 0.4m)    // the m creates a decimal constant
{
    Console.WriteLine("Hello");
}
于 2013-09-06T02:42:23.880 回答
0

当您减去浮点数的最重要部分时,由于减法结果与被减数相比具有较小的量级,因此该结果中存在许多额外的“人为”精度。而且由于原始数字没有被精确表示(几乎总是二进制浮点的情况),额外的精度看起来像垃圾。

举一个更极端的例子(原则上相同):

double x = 987654321098.4 - 987654321098.0;
// x becomes 0.4000244140625

这里的数量级变化很大。在原始示例中:

3.4 - 3.0

结果,大约。0.4,仍然小于约八分之一。3.4,所以那里有三个额外的精度。

于 2013-09-07T15:02:32.543 回答