打印非常大的浮点数

时间:2012-06-10 17:00:09

标签: c++ c floating-point standards printf

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

int main()
{
    printf("%f\n", FLT_MAX);
}

GNU的输出:

340282346638528859811704183484516925440.000000

Visual Studio的输出:

340282346638528860000000000000000000000.000000

C和C ++标准是否允许这两种结果?或者他们是否要求特定的结果?

请注意FLT_MAX = 2^128-2^104 = 340282346638528859811704183484516925440

3 个答案:

答案 0 :(得分:6)

我认为C99标准的相关部分是7.19.6.1第13页中的“推荐做法”:

  

对于eEfFgG次转化,如果有效小数位数为最多   DECIMAL_DIG,然后结果应该正确舍入。如果数量   有效十进制数字大于DECIMAL_DIG,但源值完全正确   用DECIMAL_DIG数字表示,那么结果应该是精确的   尾随零的表示。否则,源值以2为界   相邻的十进制字符串 L &lt; U ,两者都有DECIMAL_DIG个有效数字;价值   结果十进制字符串 D 应满足 L &lt; = D &lt; = U ,并附加额外规定那   错误应该有一个正确的符号表示当前的舍入方向。

我的印象是,这允许在这种情况下可能印刷的一些余地;所以我的结论是VS和GCC在这里都是合规的。

答案 1 :(得分:1)

C标准允许两者(C ++只是引入C标准)

从5.2.4.2.2第10部分的draft version

  

以下列表中给出的值应替换为常量表达式   实现定义的值大于或等于显示的值:
    - 最大可表示的有限浮点数,(1 - b -p)b emax

FLT_MAX 1E+37

和visual C ++ 2012有

#define FLT_MAX         3.402823466e+38F        /* max value */

答案 2 :(得分:0)

代码本身存在缺陷,因为它使用%f的值大于floatdouble中的重要性。通过这样做,你要求在幕后看到无意义的保护位或转换为十进制时产生的其他浮点噪声。

显然,你不应该期望在本田制造发动机后产生的金属屑与丰田相比有任何一致性。永远不要对这种一致性有任何明智的期望。

显示此类数字的正确方法是使用“科学”格式之一,例如%g提供的精度不会过度指定。在IEEE-754实现中,7个十进制数字对float很重要,double为15-16,long double约为19,__float128为34。因此,对于您给出的示例,%.15g将是正确的,假设它是在IEEE-754实现上。