为什么这个浮点比较评估为假?

时间:2013-07-06 07:02:53

标签: c++ floating-point

请考虑以下声明:

float x = 0.1 + 0.1;
if (x == 0.2) 
  return true;
else
  return false;

它不应该评估为真吗? 因为0.1 + 0.1等于0.2!

5 个答案:

答案 0 :(得分:4)

不,浮点数不是数学实数。

O.1在二进制中不能完全表示(具有有限数量的小数位),因此未在IEEE 754

中准确表示

根据经验,平等测试几乎不应该用于floatdouble个浮点数(除了奇怪的习语:if (x != x)来测试{{1}是NaN

另请参阅Fluctuat静态分析器和Some disasters caused by numerical errors。也许可以考虑使用bignums

如果您碰巧需要浮点数,请了解更多关于它们的信息。 Floating point号码是一个可怕的主题。

答案 1 :(得分:3)

您的0.1可以很容易地取0.0999999或0.1000001,它不等于0.1,这使得非常难以等于0.2(也可能是0.1999或0.2001)。

结果是确定性的,所以如果你不能在第一次比较中得到预期的话,如果你继续比较同样的事情就不能再得了。(Jim Balter的评论)

您需要检查范围,例如x>(0.2-0.001)和x<(0.2 + 0.001)

 if((x>(0.2-0.001)) &&(x<(0.2+0.001)))
 {

 }

+/- 0.001这里是你想要的间隔误差范围。不要忘记0.2是双倍的你的“x”促进加倍比较之前。当促进加倍时,它甚至可以改变更多。因此,您无法确切知道是否可以比较确切的值。

如果您需要更接近x,则需要选择小于0.001的值。如果增加其机会,则使用更大的间隔(例如:+/- 0.01)。 这可能更像是“宽容”与“精确”的问题来争论。

如果你需要比较float和float,在每个常量文字的末尾加上一个“f”就像“x&gt; = 20.01f”。

请查看arithmetic underflowarithmetic overflow,以便您可以更加确定自己在做什么。

更多信息:floating point

答案 2 :(得分:2)

在您的计算机上试试这个。你会得到你的问题的答案:

if(0.2==0.2f)
  printf("Yes\n");
else
  printf("NO\n");

答案 3 :(得分:1)

尝试使用以下代码:

float x = 0.1 + 0.1;
if (x == .2) 
  return true;
else
  return false;

浮动在比较期间被提升为双打,浮点数不如双打精确。

答案 4 :(得分:1)

0.1和0.2不能用IEEE浮点精确表示,例如,参见http://effbot.org/pyfaq/why-are-floating-point-calculations-so-inaccurate.htm