Math.Truncate(数字)问题

时间:2013-09-06 02:40:03

标签: c# .net floating-point double

正如问题所示(更多声明抱歉)我在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");
}

然而,当我尝试这样做时,它并不适合我,而且我不确定为什么它不能正常工作,我是否可以让某人对此有所了解并把它放在一边我在正确的方向吗?

2 个答案:

答案 0 :(得分:4)

singledouble是二进制浮点类型。这意味着它们无法准确表示许多十进制值(如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");
}

答案 1 :(得分:0)

当你减去浮点数的最重要部分时,因为减法结果与minuend相比具有更小的幅度,所以在该结果中存在许多额外的“人为”精度。并且因为原始数字没有完全表示(二进制浮点几乎总是如此),所以额外的精度看起来像垃圾。

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

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

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

3.4 - 3.0

结果,大约。 0.4,不到约八分之一。 3.4,那里有三个额外的精度。