在 2018/9/20 23:05, Vincent Lefevre 写道: > Actually, there may be a bug with -m32: > > #include <stdio.h> > #include <float.h> > > int main (void) > { > float f = 2147483646; > printf ("FLT_EVAL_METHOD = %d\n", (int) FLT_EVAL_METHOD); > if (f == 2147483647) > { > printf("%.20g\n", (double) f); > } > return 0; > } > > $ gcc -std=c99 -m32 -O tst.c -o tst > $ ./tst > FLT_EVAL_METHOD = 2 > 2147483648 > > Since FLT_EVAL_METHOD = 2, float_t is long double, thus shouldn't > 2147483647 be converted to long double directly (as f is regarded > as an operand of type long double), so that the result of the > equality test should be false? > > The C standard says for FLT_EVAL_METHOD = 2: "evaluate all operations > and constants to the range and precision of the long double type". > ^^^^^^^^^^^^^ > ----- ISO/IEC 9899:2017 (WG14 N2176) 5.2.4.2.2 Characteristics of floating types <float.h> 9 Except for assignment and cast (which remove all extra range and precision), the values yielded by operators with floating operands and values subject to the usual arithmetic conversions and of **floating constants** are evaluated to a format whose range and precision may be greater than required by the type. The use of evaluation formats is characterized by the implementation-defined value of FLT_EVAL_METHOD:24) ----- `2147483647` is an integer constant. This rule only describes floating constants, so it does not apply. According to '6.3.1.8 Usual arithmetic conversions', here `2147483647` is converted to a value having type `float`, which is then compared with `f` using the internal `long double` type. > Converting f first to float is contrary to the idea behind > FLT_EVAL_METHOD = 2, which is to avoid loss of precision in > intermediate operations. > -- Best regards, LH_Mouse