将System.Double与'0'(数字,int?)进行比较的正确方法

时间:2011-07-06 14:36:25

标签: c# compare

对不起,这可能是一个简单的愚蠢问题,但我需要知道确定。

我有if表达式,

void Foo()
{
    System.Double something = GetSomething();
    if (something == 0) //Comparison of floating point numbers with equality 
                     // operator. Possible loss of precision while rounding value
        {}
}

该表达式是否等于

void Foo()
{
    System.Double something = GetSomething();
    if (something < 1)
        {}
}

?因为那时我可能会遇到问题,请输入if,例如值为0.9。

6 个答案:

答案 0 :(得分:100)

那么,您需要将该值与0接近?如果你经历了很多浮点运算,在“无限精度”中可能会得到0,你可能会得到一个“非常接近”0的结果。

通常在这种情况下你想提供某种epsilon,并检查结果是否在那个epsilon中:

if (Math.Abs(something) < 0.001)

你应该使用的epsilon是特定于应用程序的 - 它取决于你正在做什么。

当然,如果结果正好为零,则可以进行简单的等式检查。

答案 1 :(得分:28)

如果从something以外的操作结果中分配了something = 0,那么最好使用:

if(Math.Abs(something) < Double.Epsilon)
{
//do something
}

编辑:此代码错误。 Epsilon是最小的数字,但不是很零。当您希望将数字与另一个数字进行比较时,您需要考虑可接受的容差。让我们说你不关心的任何超出.00001的东西。这就是你要使用的数字。该值取决于域。然而,它绝大多数肯定不会是Double.Epsilon。

答案 2 :(得分:18)

您的somethingdouble,并且您已在行中正确识别

if (something == 0)

我们在左侧有一个double(lhs),在右侧有一个int(rhs)。

但现在看来你认为lhs会被转换为int,然后==符号会比较两个整数。那是会发生什么。从 double int转换为显式,并且不会“自动”发生。

相反,恰恰相反。 rhs转换为double,然后==符号成为两个双精度之间的相等测试。此转换是隐式的(自动)。

编写

被认为更好(有些人)
if (something == 0.0)

if (something == 0d)

因为那时候你正在比较两个双打。然而,这只是风格和可读性的问题,因为编译器在任何情况下都会做同样的事情。

在某些情况下,在Jon Skeet的答案中引入“容忍度”也是相关的,但这种容忍度也是double。如果你愿意,可以当然是1.0,但它不一定是[最不严格正数]整数。

答案 3 :(得分:15)

如果您只想取消警告,请执行以下操作:

if (something.Equals(0.0))

当然,如果你知道漂移不是一个问题,这只是一个有效的解决方案。我经常这样做是为了检查我是否要除以零。

答案 4 :(得分:4)

我不认为这是平等的,老实说。考虑你自己的例子:某事= 0.9或0.0004。 在第一种情况下,它将为FALSE,在第二种情况下,它将为TRUE。处理这些类型我通常为我定义精度百分比并在该精度内进行比较。 取决于您的需求。 类似......

if(((int)(something*100)) == 0) {


//do something
}

希望这有帮助。

答案 5 :(得分:1)

下面是显示问题的示例(在LinQPad中准备-如果没有,只需使用Console.Writeline而不是Dump方法):

void Main()
{
    double x = 0.000001 / 0.1;
    double y = 0.001 * 0.01; 

    double res = (x-y);
    res.Dump();
    (res == 0).Dump();
}

x和y在理论上都是相同的,并且等于:0.00001,但是由于缺少“无限精度”,所以这些值略有不同。不幸的是,以通常的方式与0比较时,返回false的时间还不够。