13
#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.

4

3 回答 3

6

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

对于e, E, f, F, g, 和G转换,如果有效小数位数最多为 DECIMAL_DIG,则结果应正确四舍五入。如果有效小数位数大于DECIMAL_DIG但源值可以用DECIMAL_DIG数字精确表示,则结果应该是带有尾随零的精确表示。否则,源值由两个相邻的十进制字符串L < U限定,两者都具有DECIMAL_DIG有效数字;结果十进制字符串D的值应满足L <= D <= U, 并额外规定该误差应具有当前舍入方向的正确符号。

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

于 2012-06-10T17:04:52.193 回答
1

两者都是 C 标准允许的(C++ 只是导入 C 标准)

来自第 5.2.4.2.2 部分第 10 部分的草稿版本

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

FLT_MAX 1E+37

Visual C++ 2012 有

#define FLT_MAX         3.402823466e+38F        /* max value */
于 2012-06-10T17:11:38.700 回答
0

The code itself is flawed where it uses %f for a value larger than significance held in a float or double. By doing so you are asking to see "behind the curtain" as to the meaningless guard bits or other floating point noise generated in the conversion to decimal.

Clearly you should not expect any consistency in the metal filings generated after making an engine at Honda versus at Toyota. Nevermind any sensible expectation of such consistency.

The proper way to display such numbers is by using one of the "scientific" formats such as %g provided precision is not over-specified. On IEEE-754 implementations, 7 decimal figures are significant for float, 15-16 for double, about 19 for long double, and 34 for __float128. So, for the example you have given, %.15g would be proper, assuming it is on a IEEE-754 implementation.

于 2012-06-10T17:23:58.453 回答