浮点格式和 isinf()

Floating point formats and isinf()

我目前正在处理 C++ 中的浮点值。 考虑以下 C++ 片段:

#include <cmath>
#include <cstring>
#include <iostream>

int main() {
    long double num;

    // Set num to a large, valid, floating point value
    memset(&num, 0xcc, sizeof(num));

    std::cout << "num = " << num << std::endl;
    std::cout << "isinf(num) = " << isinf(num) << std::endl;
    std::cout << "std::isinf(num) = " << std::isinf(num) << std::endl;

    return 0;
}

根据 Wikipedia, this creates an 80 bit extended precision 浮点值,因为我在 x86 机器上使用 GCC。因此,浮点值是 0xcccc cccc cccc cccc cccc 并且应该是有效值。

有趣的是,输出如下:

num = -4.77987e+986
isinf(num) = 1
std::isinf(num) = 0

这让我想知道:

isinf,来自 cmath 的函数,旨在与 C 语言兼容,采用 double。当传递给该函数时,您的 long double 参数会自动转换为 double。转换为 double 会根据浮点舍入规则生成 +inf(任何大于限制的数字本身略大于 DBL_MAX 会被舍入为 +inf)。

相比之下,std::isinfoverloaded,可以取一个long double。当你传递给它一个 long double 时,参数不会被转换并且 std::isinf 可以告诉它它不是无限的。


尝试回答您的其他问题:

  • isinf是宏还是函数是一个小细节。知道它是一个宏只是方便那些想要#undef它的程序员。无论是函数还是保证是宏,它的行为都是一样的(将其参数转换为double)。

  • DBL_MAXLDBL_MAX 来自 float.h/cfloat 足以指示区分 IEEE 754 双精度(64 位格式)或扩展的 80 位格式。您还可以查看其他宏,例如 DBL_MANT_DIGLDBL_MANT_DIG,如果您想要确定您的代码在 20 年内识别四精度时广泛的处理器实现它(这不是2017 年的案例)。不建议查看 sizeof(long double),因为对于 80 位浮点格式,此值可以是 10、12 或 16,具体取决于编译器填充它的程度,值 16 也可以表示四精度.