【问题标题】:What is the difference between ! ( x < y ) and x >= y in C++?和有什么区别! ( x < y ) 和 x >= y 在 C++ 中?
【发布时间】:2012-01-05 03:16:18
【问题描述】:

在浏览 EASTL 时,我偶然发现了一行奇特的代码。以下链接显示了感兴趣的行号为 1870 的文件。

https://github.com/paulhodge/EASTL/blob/master/include/EASTL/algorithm.h

该行的代码是if(!(value &lt; *i))。评论说“我们总是用

写这样的比较有什么好处(也许我忽略了一些上下文)?如果不是,为什么EASTL的作者特意写成这样,甚至还特意评论呢?一致性是唯一的原因吗?

【问题讨论】:

  • 在浮点数中,它们是不同的,因为与 NaN 的比较总是返回 false。
  • 听起来像是一个非常具体的处理器/汇编器/编译器类型优化。此代码是否针对特定的处理器/编译器等
  • @AdrianCornish:它与优化无关,与 C++ 无关,彼此之间没有默认运算符。
  • 基本上它应该只是意味着 EASTL 遵循 C++ 标准 STL 部分的约定。

标签: c++ comparison-operators


【解决方案1】:

这意味着您只需要为容器值类型提供&lt;==。这也意味着您减少了这些类型的可变性(因为所有算法都使用!(a&lt;b) 来表示a&gt;=b!(a==b) 来表示a!=b);否则,&gt;=!= 可能会返回不一致的结果。

【讨论】:

    【解决方案2】:

    在 C++ 中,您可以重载 &lt; 运算符,使其行为与 &gt;= 相反,因此不能保证它们是等效的。

    此外,在任何 IEEE 浮点实现中,NaN &lt; NaN 为假,NaN &gt;= NaN 也是如此,因此即使NaN &gt;= NaN 为假,!(NaN &lt; NaN) 也为真。

    【讨论】:

      【解决方案3】:

      我看到了至少一个区别。如果其中一个数字是 QNAN(浮点 0/0),那么如果 a 或 b 中的任何一个是 QNAN,则 !(a =b,它将始终返回 false

      【讨论】:

      • 其实这种行为很烦人。在数学上,&lt; 的属性之一是反对称。这意味着!(a &lt; b) 意味着b &lt; a。人们有意识地选择违反这个属性让我感到困惑,它抛出了许多算法......
      • @SteveJessop:是的,抱歉,有点不对劲。真正的关系是:!(a &lt; b) and !(b &lt; a) =&gt; a == b
      • @Matthieu:确实很烦人,但你对反对称的定义是错误的。考虑a == b,那么!(a&lt;b) 并不意味着b&lt;a。因此,即使对于不奇怪的类型,也不要使用该定义 :-) 正确的定义是 a &lt; b 意味着 !(b&lt;a),实际上 NaN 确实满足,因为 lhs 永远不会为真。它在 &lt; 方面遗漏的属性是 order-equivalence 不具有传递性,但 &lt; on float 是严格的偏序。
      • 我认为 NaN 位于浮点上定义的排序之外的理由是 IEEE 提供了足够的保证,您可以小心避免生成一个。不要取负数的平方根等。如果您愿意假装所有生成 NaN 的操作都有 UB,那么您只需要担心 NaN 输入对面向公众的库函数的含义。
      【解决方案4】:

      仅使用小于运算符,您可以模拟所有其他比较运算符。这使其更加一致,并允许您在需要参数化比较时使用单个模板参数。例如,标准的排序容器和算法使用std::less&lt;T&gt; 作为默认模板比较器。

      operation  equivalent
      x < y      x < y
      x > y      y < x
      x <= y     !(y < x)
      x >= y     !(x < y)
      x == y     !(x < y) && !(y < x)
      x != y     (x < y) || (y < x)
      

      对于那些排序不重要的操作,使用运算符== 会更简单、更有效。

      【讨论】:

      • 标准库也使用equal_to (==)进行相等检查。
      猜你喜欢
      • 1970-01-01
      • 2015-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      相关资源
      最近更新 更多