【问题标题】:3-way comparison of floating-point numbers [closed]浮点数的三向比较[关闭]
【发布时间】:2022-01-18 15:34:03
【问题描述】:

给定一对浮点数,执行三路比较的最佳方法是什么,即返回负数、零或正数,具体取决于第一个数是小于、等于还是大于第二个数字?

一些语言,如 Perl、Java 和 C++20,内置了这个运算符,或者在标准库中。但是,我问的是如何用纯 C 语言做到这一点。

如果输入是整数,那么编写一对双向比较将是一件简单的事情。但是由于 NaN 的特殊行为,浮点输入更复杂。考虑到这一点,什么是合适的方法?

【问题讨论】:

  • 您可能还想考虑一个“epsilon”来表示相等。无论如何,你需要这个做什么?我不记得我需要这样的任何情况。
  • 您希望如何提供结果?作为 -1、0 或 +1 的整数,表示小于、等于或大于,或作为任何负数、零或任何正数的整数,表示小于、等于、等于或大于比?或者是其他东西?如果一个或两个操作数都是 NaN,你想要什么结果?
  • 需要区分4种不同的比较结果,小于、等于、大于、无序。我可能会首先使用isunordered(x, y) 宏来测试它。您将需要一个 4 向值来表示它。
  • @BarmakShemirani 1) 如果它在一个系统上工作,它证明什么。其他系统可能会给出其他结果。 2) 您是否还检查了最小值、最大值、NaN 和无穷大值? 3)OP没有告诉我们所需结果的数据类型。它可能不是浮点数。
  • rwallace,返回类型必须是intdouble 怎么样?这允许返回NAN,其中xyNAN。在比较 +/- 0.0 和 +/- 0.0(4 种组合)时,我希望您希望返回 value 为 0.0。如果有时为 -0.0 或必须为 +0.0,可以吗?

标签: c floating-point comparison-operators


【解决方案1】:

考虑到 (NAN) 的适当方法是什么?

返回一个 FP 类型以允许 4 个不同的返回值:-1.0、0.0、1.0、NAN。

在涉及 -0.0 的特定情况下,Below 也会返回 -0.0。

#include <math.h>

double fcmp(double a, double b) {
  if (isunordered(a, b)) return NAN;
  if (a > b) return 1.0; 
  if (a < b) return -1.0; 
  return a - b;
} 

我什至会考虑在NAN 时传播ab 以维护NAN 有效负载。可能存在许多不同的非数字。

double fcmp(double a, double b) {
  if (isnan(a)) return a;
  if (isnan(b)) return b;
  ...
} 

但是让我们看一下用于排序的 3-way 与 qsort() 一样。一个问题是在哪里放置 NAN?一个共同的目标是将它们放在列表的最后——即所有的 NAN 都比其他的都大。为此,我们需要一致地进行比较,即使两个操作数都是具有不同负载的 NAN。

// All NAN considered greater than others
// return 0, a positive or negative int.
int fcmp_for_qsort(const void *ap, const void *bp) {
  double a = *(const double *) ap;
  double b = *(const double *) bp;
  if (isnan(a)) {
    if (isnan(b)) {
      return 0;
    }
    return 1;
  }
  if (isnan(b)) -1;
  return (a > b) - (a < b);
} 

【讨论】:

    【解决方案2】:

    返回 -1, 0, 1 表示小于、等于和大于,加上一些其他值表示不可比较:

    #include <math.h>
    
    int cmp(double a, double b) {
        if (isunordered(a, b)) {
            /* at least one NaN, return whatever you feel is appropriate */
            return 42;
        }
        return (a>b) - (a<b);
    }
    

    如果您想与 epsilon 进行模糊比较,请随意使 &lt;&gt; 更复杂...

    【讨论】:

    • a!=a || b!=b 测试可以替换为isunordered(a,b)
    • 你确定你的答案吗?从这个链接:stackoverflow.com/questions/38798791/nan-comparison-rule-in-c-c/… 看起来更复杂
    • “== 和 != 运算符似乎不受限于 NaN 的 IEEE 754 行为,正如@AlexD 的回答中已经指出的那样。但是, 比较宏是必需的遵循等同于 IEEE 754 的 NaN 规则。"
    • 请注意,这种比较方法不适用于qsort(),因为cmp(NAN, not NAN) 不是-cmp(not NAN, NAN)(除非NAN 返回值为0)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    相关资源
    最近更新 更多