对不起,这可能是一个简单的愚蠢问题,但我需要知道确定。
我有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。
答案 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)
您的something
是double
,并且您已在行中正确识别
if (something == 0)
我们在左侧有一个double
(lhs),在右侧有一个int
(rhs)。
但现在看来你认为lhs会被转换为int
,然后==
符号会比较两个整数。那是不会发生什么。从 double
到 int
的转换为显式,并且不会“自动”发生。
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
的时间还不够。