我目前正在处理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,这会创建一个80位extended precision浮点值,因为我在x86机器上使用GCC。因此,浮点值为0xcccc cccc cccc cccc cccc
,并且应该是有效值。
有趣的是,输出结果如下:
num = -4.77987e+986
isinf(num) = 1
std::isinf(num) = 0
这让我想知道:
isinf
和std::isinf
表现得与众不同?哪一个值得信任?-std=c++98
,我仍然得到相同的行为。在这种情况下,甚至不能定义std::isinf
吗?答案 0 :(得分:6)
isinf
,cmath
中旨在与C语言兼容的函数需要double
。传递给该函数时,您的long double
参数会以静默方式转换为double
。转换为double
会根据浮点舍入规则生成+inf
(任何大于限制本身略大于DBL_MAX
的数字都会舍入为+inf
)。
相比之下,std::isinf
为overloaded,可以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也可以表示四精度