在我关于32位十进制数字的浮点/双精度分析的问题中,一个答案说看一下
__float128
。
我使用了它,编译器可以找到它,但我无法打印它,因为编译器找不到标头
quadmath.h
。
所以我的问题是:
__float128
是标准的,对吗?quadmath.h
不是标准吗?这些答案没有帮助:
ref也没有帮助。
请注意,我不想使用任何非标准库。
[编辑]
如果该问题有答案,即使答案是否定的,也会很有用。
使用 boost 库对我来说是最好的答案:
#include <boost/multiprecision/float128.hpp>
#include <boost/math/special_functions/gamma.hpp>
using namespace boost::multiprecision;
float128 su1= 0.33333333333333333q;
cout << "su1=" << su1 << endl;
记得链接这个库:
-lquadmath
使用 GNU-Fortran 工作!它允许以不同的精度运行相同的程序:单精度(32 位)、双精度(64 位)、扩展精度(80 位)和四精度(128 位)。您不必在程序中进行任何更改,只需为所有浮点写入“实数”即可。浮点数的大小由编译器选项 -freal-4-real-8、-freal-4-real-10 和 -freal-4-real-16 设置。
不,它不是标准的——无论是类型还是标题。这就是该类型具有双下划线(保留名称)的原因。显然,quadmath.h 提供了一个
quadmath_snprintf
方法。当然,在 C++ 中你会使用 <<
。
__float128
是供应商扩展。
在 C23 中,
_FloatN
表示 N = 16, 32, 64, 128
或大于 128 的 32 的倍数是编译器可以提供的标准化扩展。所以 _Float128
将是标准类型。要打印类型,请使用 strfromfN
将其转换为字符串:
void print(_Float128 fp) {
char buf[32 + sizeof(".e+99999")];
int sz = strfromf128(buf, sizeof buf, "%.32g", fp);
fwrite(buf, 1, sz, stdout);
}
https://godbolt.org/z/E7W6a4r8d
在 C++23 中,以及
_FloatN
可能由编译器作为扩展提供,std::float128_t
也作为标准 128 位浮点类型提供。
如果
operator<<
有重载,它是实现定义的,所以你可以简单地使用std::cout
,但是会有一个std::formatter
专门化,所以std::format
可以用来创建一个字符串:
void print(std::float128_t fp) {
std::println("{:.32g}", fp); // std::println is C++26
// C++23: `std::cout << std::format("{:.32g}\n", fp);`
}
https://godbolt.org/z/5sahahn4P
在C23/C++23之前,128位浮点没有标准类型。有时
long double
是 128 位,但这种情况很少见(更有可能是 80 位或与常规 double
相同的 64 位)。所以你必须使用编译器扩展或软件模拟库。