2

对于以下代码,

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

int main(void) {
    printf("double max = %??\n", DBL_MAX);
    printf("double min = %??\n", DBL_MIN);
    printf("double epsilon  = %??\n", DBL_EPSILON);
    printf("float epsilon  = %??\n", FLT_EPSILON);
    printf("float max = %??\n", FLT_MAX);
    printf("float min = %??\n\n", FLT_MIN);
    return 0;
}

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

4

3 回答 3

7

使用与这些类型的任何其他值相同的格式:

#include <float.h>
#include <stdio.h>
int main(void) {
    printf("FLT_MAX = %g\n", FLT_MAX);
    printf("DBL_MAX = %g\n", DBL_MAX);
    printf("LDBL_MAX = %Lg\n", LDBL_MAX);
}

类型参数float被提升为double可变参数函数,例如printf,这就是为什么你对两者使用相同的格式。

%f使用不带指数的十进制表示法打印浮点值,这将为您提供非常长的(大部分无关紧要的)数字字符串,用于非常大的值。

%e强制使用指数。

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

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

FLT_MAX = 3.40282e+38
DBL_MAX = 1.79769e+308
LDBL_MAX = 1.18973e+4932

正如 Eric Postpischil 在评论中指出的那样,上面只打印了值的近似值。您可以通过指定精度来打印更多位数(您需要的位数取决于类型的精度);例如,您可以替换%g%.20g.

或者,如果您的实现支持它,C99 增加了以十六进制打印浮点值的能力,并具有尽可能高的精度:

printf("FLT_MAX = %a\n", FLT_MAX);
printf("DBL_MAX = %a\n", DBL_MAX);
printf("LDBL_MAX = %La\n", LDBL_MAX);

但结果不像通常的十进制格式那样易于人类阅读:

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

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

于 2013-09-14T01:29:32.123 回答
1

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

#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;
}

在 C 2011 中,您可以使用更具体FLT_DECIMAL_DIGDBL_DECIMAL_DIG, 和LDBL_DECIMAL_DIG代替DECIMAL_DIG.

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

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

于 2013-09-14T03:09:49.027 回答
0

您可以使用我对 The C Programming Language 中练习 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 计算的。完整的解决方案可通过链接获得: https ://github.com/mat90x/tcpl/blob/master/types_ranges.c

于 2018-05-17T17:49:02.750 回答