【问题标题】:Float comparison with zero-initialised value in C++与 C++ 中的零初始化值进行浮点比较
【发布时间】:2018-04-14 09:13:43
【问题描述】:

使用 '==' 运算符来确定 C++ 中的 double 变量自初始化为 0.0 后是否已更改是否安全?

出于性能原因,如果嵌套 for 循环中的值已经计算过,我希望避免重新计算该值。

如果认为不安全: 这会导致误报(即表达式返回 true,尽管值不等于 0.0)、误报(即表达式返回 false,尽管值确实为 0.0)或两者/未确定的行为?

我正在使用 C++-14 和 GNU C++ 编译器 v5.4。

【问题讨论】:

  • 非常相关:Is floating point math broken? 简而言之,一旦您进行了一些计算,浮点值完全等于某个值的可能性很小。
  • "判断 C++ 中的 double 变量自初始化为 0.0 后是否发生了变化?" 如果将其更改为 3.1416 然后再次设置为 0.0 会怎样?它已经改变了,但它是==0.0
  • 尽管如此,如果一个未触及的变量仅仅因为我同时在某个地方使用了浮点运算而改变,这不是很奇怪吗?据我所知,0 具有精确的浮点表示,因此 (0.0 == 0.0) 可以预测为 true。
  • @Calyx 是的,0.0 是可以精确表示的值之一,因此比较是安全的。但是你不能断定初始化为0.0的东西没有改变,因为稍后它是==0.0
  • 为此我使用了初始化为NAN-0.0 的技巧。

标签: c++ floating-point floating-accuracy


【解决方案1】:

在 C++ 中,当且仅当 x 为零时,表达式 x == 0. 的计算结果为 true。

您可能有误报或误报的唯一意义是:

  • x 是在理想的精确数学结果非零时产生零的计算结果,反之亦然。换句话说,问题在于x 不包含您想要的值,而不是与零比较无法正常工作。
  • 比较不是简单的对象x,而是使用浮点表达式,如x/y == 0.。 C++ 允许以比名义类型更精确的方式计算表达式。当值由强制转换分配或转换时,该超额精度将被丢弃。因此,比较可能表明表达式不为零,即使将其分配给对象会在对象中产生零。

【讨论】:

    猜你喜欢
    • 2013-11-19
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多