C 和 C++ 编译器如何实现浮点数的相等性判定?

How do C and C++ compilers implement the decision of equality for float numbers?

例如,

float a = 1.0;
float b = 1.2;

puts(a == b? "equal": "not equal");

编译器是按位还是其他方式处理?

(我知道用“==”来判断浮点数是否相等不是一个好的选择,我只是想知道编译器是如何处理这种情况的。)

我假设你的意思是程序编译后,它如何比较两个浮点数。花车的存放方式非常独特。它按符号、指数和分数存储,如 here 所示。因此,除非绝对相等,程序甚至会将 1 和 1.000000000001 视为不同。要检查它们是否 almost 相等,您可以使用以下命令:

bool AlmostEqualRelativeOrAbsolute(float A, float B,
            float maxRelativeError, float maxAbsoluteError)
{
    if (fabs(A - B) < maxAbsoluteError)
        return true;
    float relativeError;
    if (fabs(B) > fabs(A))
        relativeError = fabs((A - B) / B);
    else
        relativeError = fabs((A - B) / A);
    if (relativeError <= maxRelativeError)
        return true;
    return false;
}

代码是从here获得的,你可能想在网站上阅读更多内容。

gcc 和 clang 使用 UCOMISS x86/x64 指令。

来源:tried it-O3 并检查了汇编输出。

一般的、完整的答案是浮点数是根据 IEEE 754 规范进行比较的。

具体回答你的问题,大多数情况下两个浮点数是按位比较的,有少数例外情况:

  • 正负零被认为是相等的
  • NaN 被认为不等于一切,甚至不等于 NaN 本身
  • 次正规可能在某些操作模式下比较等于零和其他次正规(例如"flush subnormals to zero")
  • 除了这些例外,使用常规的按位比较