虽然long double提供了更高的精度和更大的范围,但它的兼容性和移植性不好。不同的编译器和平台对long double的实现有所不同。因此,在跨平台开发时,使用long double需要特别小心,确保在所有目标平台上都能正确运行。
long double类型sizeof()实测:存储空间
测试代码:
#include <iostream>
int main()
{
std::cout << sizeof(long double) << std::endl;
return 0;
}
- g++.exe (MinGW-W64 x86_64-posix-seh, built by Brecht Sanders) 11.3.0: 16 (128bits)
- c++Builder12.2
- bcc32c(基于clang5): 10 (80bits)
- bcc64x(基于clang15,使用
-mlong-double-128
):8 (64bits)
- VC++,微软的long double 就是double,只有64位:https://learn.microsoft.com/zh-cn/cpp/build/ieee-floating-point-representation?view=msvc-140
- clang
- 为了处理和windows的新的sdk的兼容性问题,clang的新版本(15)竟然把
-mlong-double-128
选项给移除了,统一性做的并不好: https://github.com/flang-compiler/flang/pull/1340 - 一位c++Builder用户抱怨 Clang (无论主机是什么) 不实现使用 quadmath 128 位浮点库,即使已经为此自己做了很多工作: https://github.com/boostorg/multiprecision/issues/216
- 为了处理和windows的新的sdk的兼容性问题,clang的新版本(15)竟然把
用圆周率测试long double
测试代码:
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
int main()
{
std::cout << "sizeof(long double):"<<sizeof(long double) << std::endl;
// PI,有效十进制位数40,对应的字符串
std::string str_pi = "3.141592653589793238462643383279502884197";
//测试long double 的变量,需要转为对应的字符串
long double pi=3.141592653589793238462643383279502884197L;
std::ostringstream out;
out.precision(39);
out << std::fixed << pi;
//long double类型 pi 对应的字符串
std::string str_pi_from_long_double = out.str();
std::cout <<"pi: "<< str_pi << std::endl;
std::cout <<"pi_from_long_double:"<< str_pi_from_long_double << std::endl;
//计算long double 精度
int n=2;//精度
while(n<40) {
if (str_pi[n]!=str_pi_from_long_double[n]) {
std::cout << "The number of significant digits in long double is:" <<n-1<< std::endl;
break;
}else {
n++;
}
}
}
g++:
sizeof(long double):16
pi: 3.141592653589793238462643383279502884197
pi_from_long_double:3.141592653589793238512808959406186204433
The number of significant digits in long double is:19 `
bcc32c:
sizeof(long double):10
pi: 3.141592653589793238462643383279502884197
pi_from_long_double:3.141592653589793238000000000000000000000
The number of significant digits in long double is:19
bcc64x:
sizeof(long double):8
pi: 3.141592653589793238462643383279502884197
pi_from_long_double:3.141592653589793115997963468544185161591
The number of significant digits in long double is:16
结果:
- bcc32c:用80位存储19位有效数字的pi
- g++ :用 128位存储pi,但只有19位有效
- bcc64x:用64位存储pi
如果传一个double(字面量末尾没有加L):
long double pi=3.141592653589793238462643383279502884197;
g++:
pi: 3.141592653589793238462643383279502884197
pi_from_long_double:3.141592653589793115997963468544185161591
The number of significant digits in long double is:16
bcc32c:
sizeof(long double):10
pi: 3.141592653589793238462643383279502884197
pi_from_long_double:3.141592653589793116000000000000000000000
The number of significant digits in long double is:16
bcc64x:
sizeof(long double):8
pi: 3.141592653589793238462643383279502884197
pi_from_long_double:3.141592653589793115997963468544185161591
The number of significant digits in long double is:16
long double相关参考资料
- 真正的四精度浮点数可能要使用
__float128
: Floating Types (Using the GNU Compiler Collection (GCC)) - x86 64pc一般实现的是80位long double: 扩展精度 – 维基百科,自由的百科全书
- 实现:x86 体系结构(特别是 x86 上的 x87 浮点指令)支持 80 位扩展精度运算,在 GNU C 编译器中,无论用于该类型的物理存储如何(可以是 96 位或 128 位),在 x86 处理器上都是 80 位扩展精度:long double – 维基百科,自由的百科全书
- IEEE 浮点运算标准 (IEEE 754) 是浮点运算的技术标准,最初由电气和电子工程师协会 (IEEE) 于 1985 年制定。该标准解决了在各种浮点实现中发现的许多问题,这些问题使它们难以可靠和可移植地使用。许多硬件浮点单元使用 IEEE 754 标准:IEEE 754 – 维基百科,自由的百科全书
正文完