sizeof long double和precision不匹配?

考虑以下C代码:

#include  int main(int argc, char* argv[]) { const long double ld = 0.12345678901234567890123456789012345L; printf("%lu %.36Lf\n", sizeof(ld), ld); return 0; } 

Ubuntu x64 13.04下用gcc 4.8.1编译,它打印:

 16 0.123456789012345678901321800735590983 

这告诉我一个长双倍权重16字节,但小数似乎只对第20位。 这怎么可能? 16个字节对应四元组,四元组给出33到36个小数。

C实现中的long double格式使用Intel格式,带有一位符号,一个15位指数和一个64位有效数字(总共十个字节)。 编译器为它分配16个字节,这很浪费但对于诸如对齐之类的东西很有用。 但是,64位仅提供log 10 (2 64 )个有效数字,大约为20位。

long double各种C实现可以具有变体范围和精度。 sizeof暗示为基础浮点表示法,但未指定它。 long double不需要有33到36位小数。 它甚至可以具有与double精度完全相同的表示。

如果没有硬编码精度,但使用所有可用的精度而不是过度,建议:

 const long double ld = 0.12345678901234567890123456789012345L; printf("%.*Le\n", LDBL_DIG + 3, ld); printf("%.*Le\n", LDBL_DIG + 3, nextafterl(ld, ld*2)); 

这打印出来(在我的eclipse intel 64位上),当然,你的可能会有所不同。

 1.234567890123456789013e-01 1.234567890123456789081e-01 

[编辑]

经过审核,+2就足够了。 最好使用LDBL_DECIMAL_DIG 。 请参阅Printf宽度说明符以保持浮点值的精度

 printf("%.*Le\n", (LDBL_DIG + 3) - 1, ld); printf("%.*Le\n", LDBL_DECIMAL_DIG - 1, ld); 

sizeof运算符返回数据类型的字节大小。 浮点格式类型实际上与数据类型的字节大小不可比,其他更大的大小通常意味着更好的精度。