如何在C中打印最大可能的浮点和双精度?

如何在C中打印最大可能的浮点和双精度?,c,floating-point,double,printf,limits,C,Floating Point,Double,Printf,Limits,对于以下代码 #包括 #包括 #包括 内部主(空){ printf(“双最大值=%?\n”,DBL_最大值); printf(“双最小值=%?\n”,DBL\u最小值); printf(“双ε=%?\n”,DBL\uε); printf(“浮点ε=%?\n”,浮点ε); printf(“最大浮点数=%??\n”,最大浮点数); printf(“浮点最小值=%?\n\n”,浮点最小值); 返回0; } 为了让printf将各种数量显示为大小合适的十进制数字,我必须使用哪些说明符来代替 #包括 #

对于以下代码

#包括
#包括
#包括
内部主(空){
printf(“双最大值=%?\n”,DBL_最大值);
printf(“双最小值=%?\n”,DBL\u最小值);
printf(“双ε=%?\n”,DBL\uε);
printf(“浮点ε=%?\n”,浮点ε);
printf(“最大浮点数=%??\n”,最大浮点数);
printf(“浮点最小值=%?\n\n”,浮点最小值);
返回0;
}

为了让printf将各种数量显示为大小合适的十进制数字,我必须使用哪些说明符来代替

#包括
#包括
内部主(空){
printf(“FLT_MAX=%g\n”,FLT_MAX);
printf(“DBL\u MAX=%g\n”,DBL\u MAX);
printf(“LDBL\u MAX=%Lg\n”,LDBL\u MAX);
}
对于变量函数,如
printf
,类型为
float
的参数被提升为
double
,这就是为什么两者使用相同的格式

%f
使用无指数的十进制表示法打印浮点值,这将为非常大的值提供一个非常长的(几乎不重要的)数字字符串

%e
强制使用指数

%g
使用
%f
%e
,具体取决于所打印数字的大小

在我的系统上,上面打印了以下内容:

FLT_MAX=3.40282e+38
DBL_MAX=1.79769e+308
LDBL_MAX=1.18973e+4932
正如Eric Postdischil在一篇评论中指出的那样,上面只打印了这些值的近似值。通过指定精度,可以打印更多的数字(所需的位数取决于类型的精度);例如,您可以将
%g
替换为
%.20g

或者,如果您的实现支持,C99添加了以十六进制打印浮点值的功能,精度可以达到所需的程度:

printf(“FLT\u MAX=%a\n”,FLT\u MAX);
printf(“DBL\u MAX=%a\n”,DBL\u MAX);
printf(“LDBL\u MAX=%La\n”,LDBL\u MAX);
但结果不像通常的十进制格式那么容易让人阅读:

FLT_MAX = 0x1.fffffep+127
DBL_MAX = 0x1.fffffffffffffp+1023
LDBL_MAX = 0xf.fffffffffffffffp+16380

(注意:
main()
是一个过时的定义;请改用
int main(void)

要打印最大值的近似值,用足够的数字表示实际值(将打印值转换回浮点值的结果应为原始值),可以使用:

#include <float.h>
#include <stdio.h>


int main(void)
{
    printf("%.*g\n", DECIMAL_DIG, FLT_MAX);
    printf("%.*g\n", DECIMAL_DIG, DBL_MAX);
    printf("%.*Lg\n", DECIMAL_DIG, LDBL_MAX);
    return 0;
}
#包括
#包括
内部主(空)
{
printf(“%.*g\n”,十进制数字,FLT\u MAX);
printf(“%.*g\n”,十进制数字,DBL\u最大值);
printf(“%.*Lg\n”,十进制数字,LDBL\u最大值);
返回0;
}
在C 2011中,您可以使用更具体的
FLT\u DECIMAL\u DIG
DBL\u DECIMAL\u DIG
,和
LDBL\u DECIMAL\u DIG
来代替
DECIMAL\u DIG

要打印精确值,而不是近似值,需要指定更高的精度<代码>(int)(log10(x)+1)数字应该足够了


最小值和ε的近似值可以用同样的方法以足够的精度打印出来。但是,计算精确值所需的位数可能比计算最大值更复杂。(从技术上讲,这在异国情调的C实现中可能是不可能的。例如,一个基数为3的浮点系统的最小值不能用任何有限的十进制数字来表示。我不知道有任何这样的实现在使用。)

您可以使用C编程语言的练习2.1解决方案中的最后三个打印

// float or IEEE754 binary32
printf(
    "float: {min: %e, max: %e}, comp: {min: %e, max: %e}\n",
    FLT_MIN, FLT_MAX, pow(2,-126), pow(2,127) * (2 - pow(2,-23))
    );
// double or IEEE754 binary64
printf(
    "double: {min: %e, max: %e}, comp: {min: %e, max: %e}\n",
    DBL_MIN, DBL_MAX, pow(2,-1022), pow(2,1023) * (2 - pow(2,-52))
    );
// long double or IEEE754 binary 128
printf(
    "long double: {min: %Le, max: %Le}, comp: {min: %Le, max: %Le}\n",
    LDBL_MIN, LDBL_MAX, powl(2,-16382), powl(2,16383) * (2 - powl(2,-112))
    );
显然,最大值是根据IEEE 754计算的。完整的解决方案可通过以下链接获得:

阅读手册页并做一些实验。例如:@CharlieBurns:No,
float
被提升为
double
,因此相同的格式(
%f
%e
,或
%g
)用于两者。@AdamBurry:cppreference.com通常被认为比cplusplus.com更好:@KeithThompson,谢谢你的提示。我会查出来。
DBL\u MAX
是最大的有限
double
INFINITY
稍微大一点。这实际上并不符合问题的要求,因为它不打印可能的最大值,只打印它们的近似值。当从十进制类型转换回浮点类型时,这些近似值不足以表示正确的值。Mac OS X 10.6.8上的Apple GCC 4.2.1将在说明符中添加足够精度的情况下打印完整、准确的值。
%f
将在适当的实现中为您提供准确的值。@R..:当然,如果您不介意近5000位(取决于实际精度)对于
LDB_MAX
。建议不要在OP post中使用
%f
和DBL_EPSILON,因为使用
DBL_DECIMAL_DIG
而不是
DBL_DIG
会导致无效的“0.000000”。+1。第一种方法最适合这种情况。