Strange behavior when casting an int to float in C

前端 未结 5 1686
予麋鹿
予麋鹿 2021-02-18 14:27

I have a doubt concerning the output of the following C program. I tried to compile it using both Visual C++ 6.0 and MinGW32 (gcc 3.4.2).

#include 

        
5条回答
  •  醉话见心
    2021-02-18 14:57

    In both cases, code seeks to convert from some integer type to float and then to double.. The double conversion occurs as it is a float value passed to a variadic function.

    Check your setting of FLT_EVAL_METHOD, suspect it has a value of 1 or 2 (OP reports 2 with at least one compiler). This allows the compiler to evaluate float "... operations and constants to the range and precision" greater than float.

    Your compiler optimized (float)x going directly int to double arithmetic. This is a performance improvement during run-time.

    (float)2147483647 is a compile time cast and the compiler optimized for int to float to double accuracy as performance is not an issue here.


    [Edit2] It is interesting that the C11 spec is more specific than the C99 spec with the addition of "Except for assignment and cast ...". This implies that C99 compilers were sometimes allowing the int to double direct conversion, without first going through float and that C11 was amended to clearly not allow skipping a cast.

    With C11 formally excluding this behavior, modern compliers should not do this, but older ones, like OP's might - thus a bug by C11 standards. Unless some other C99 or C89 specification is found to say other-wise, this appears to be allowable compiler behavior.


    [Edit] Taking comments together by @Keith Thompson, @tmyklebu, @Matt McNabb, the compiler, even with a non-zero FLT_EVAL_METHOD, should be expected to produce 2147483648.0.... Thus either a compiler optimization flag is explicitly over-riding correct behavior or the compiler has a corner bug.


    C99dr §5.2.4.2.2 8 The values of operations 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:

    -1 indeterminable;

    0 evaluate all operations and constants just to the range and precision of the type;

    1 evaluate operations and constants of type float and double to the range and precision of the double type, evaluate long double operations and constants to the range and precision of the long double type`;

    2 evaluate all operations and constants to the range and precision of the long double type.


    C11dr §5.2.4.2.2 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

    -1 (Same as C99)

    0 (Same as C99)

    1 (Same as C99)

    2 (Same as C99)

提交回复
热议问题