如何打印最大可能的浮点数并在C中加倍?

时间:2013-09-14 01:25:18

标签: c floating-point double printf limits

对于以下代码,

#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将各种数量显示为适当大小的十进制数,我必须使用哪些说明符代替???

3 个答案:

答案 0 :(得分:5)

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

#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)。)

答案 1 :(得分: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_DIGLDBL_DECIMAL_DIG代替DECIMAL_DIG

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

可以以相同的方式以足够的精度打印最小值和epsilons的近似值。但是,计算精确值所需的位数可能比最大值更复杂。 (从技术上讲,在外来C实现中可能是不可能的。例如,基数为三的浮点系统在任何有限数量的十进制数字中都具有最小值。我不知道有任何这样的实现在使用。)

答案 2 :(得分:0)

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