mad*_*ax1 4 c++ floating-point ieee-754 c++11
我目前正在处理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;
}
Run Code Online (Sandbox Code Playgroud)
根据维基百科,这创建了一个80位扩展精度浮点值,因为我在x86机器上使用GCC.因此0xcccc cccc cccc cccc cccc,浮点值应该是有效值.
有趣的是,输出结果如下:
num = -4.77987e+986
isinf(num) = 1
std::isinf(num) = 0
Run Code Online (Sandbox Code Playgroud)
这让我想知道:
isinf和std::isinf不同?哪一个值得信任?-std=c++98,我仍然得到相同的行为.不应该std::isinf甚至在这种情况下,如何界定?isinf,cmath旨在与C语言兼容的函数,需要一个double.传递给该函数时,您的long double参数将被静默转换为double.转化为double产生+inf根据浮点舍入规则(比界限本身稍大大于任何数量的DBL_MAX被舍入到+inf).
相比之下,std::isinf是超载,可以采取long double.当你传递它时long double,参数不会被转换,并且std::isinf可以告诉它不是无限的.
要尝试回答您的其他问题:
它是一个小细节,无论isinf是宏还是函数.知道它是一个宏只对想要#undef它的程序员来说很方便.无论是函数还是保证是宏,它的行为都相同(将其参数转换为double).
DBL_MAX和LDBL_MAX从float.h/ cfloat足够指示IEEE 754双精度(64位格式)或扩展的80位格式之间进行区分.您还可以看看其他宏,如DBL_MANT_DIG和LDBL_MANT_DIG,如果你想成为肯定的是,你的代码识别,比方说,四精度20年时普遍处理器实现它(这是不是在2017年的情况).建议不要查看,sizeof(long double)因为80位浮点格式的值可以是10,12或16,具体取决于编译器填充多少,值16也可以表示四精度.