【问题标题】:Unordered floating point comparisons in CC中的无序浮点比较
【发布时间】:2016-09-15 06:39:30
【问题描述】:

C 中的默认浮点比较(例如,3.0 false。但是,编译器和处理器也有无序比较。例如,在 LLVM IR 中,fcmp instruction 都有有序和无序的变体。 C99 有一些函数可以测试 NaN。但是,除此之外我没有找到其他无序比较操作。是否有任何提供无序浮点比较的 GNU 扩展(或其他标准库函数)?

到目前为止,我只能通过检查相反的条件来实现它们。例如,为了实现无序的a >= b 比较,我改为编写有序的!(a < b),LLVM 最终将其简化为无序的比较fcmp uge double %1, %2

【问题讨论】:

  • hm?
  • 您对这里的术语有些混淆。这不是比较的“有序”或“无序”版本的问题。 fcmp uge 之类的关键字表示“无序 or 大于或等于”,而不是“无序”大于或等于比较。将其称为 >= 的“无序”版本就像将 >= 称为 > 的“相等”版本。
  • C99 也有isunordered(x, y)

标签: c floating-point llvm llvm-ir comparison-operators


【解决方案1】:

但是,除此之外我没有发现其他无序比较操作。是否有任何提供无序浮点比较的 GNU 扩展(或其他标准库函数)?

正如@user2357112 在 cmets 中观察到的那样,“无序浮点比较”不是一回事。这个词甚至没有意义。您似乎想要评估的是“x 小于 y 或两者无序”形式的谓词。

符合标准的 C 实现不能随意添加运算符,即使作为扩展也是如此。原则上,它们可以为现有运算符定义其他含义,但我不知道有任何实现可以提供您正在寻找的特定操作。正如您已经发现的那样,使用 C 的现有运算符来达到目的非常简单:

到目前为止,我只能通过检查相反的条件来实现它们。例如,为了实现一个无序的a >= b比较,我写了一个有序的!(a < b)

更新:问题在于,当操作数之一为 NaN(并且 FP 异常未被禁用)时,这些比较将引发浮点异常。但你很幸运!从C99开始,有standard macros implementing the comparisons you seek。它们保证只计算一次参数,并且不会引发浮点异常。

当然,如果您希望能够在代码中更清楚地表达您明确适应 NaN,那么您总是可以为它编写宏:

#define GE_OR_UNORDERED(x, y) (!((x) < (y)))

// ...

if (GE_OR_UNORDERED(a, b)) // ...

还请注意,所有这些都在很大程度上依赖于实现细节。尽管 C 认识到实类型可以容纳不表示浮点数的值(例如 NaN)的可能性,但它并不要求它们这样做,也没有定义关系或对这些值的算术运算。尽管现在大多数实现都使用 IEEE-754 浮点格式和运算,但它们并不是必须这样做的,而且从历史上看,有些没有这样做。

【讨论】:

  • 是的,我同意我应该想出一个更好的名字。您将如何解决我所说的有序和无序浮点比较,例如,区分两类 LLVM IR 浮点比较 (llvm.org/docs/LangRef.html#fcmp-instruction)?此外,GNU C 扩展提供一些标准 C 没有的功能也很常见。例如,它还有一些由@Eugene Sh 发布的宏。以上为标准 C 未定义的情况提供了一些有保证的行为。
  • @box:这些宏是标准的一部分,而不是扩展。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
相关资源
最近更新 更多