top | item 22068307

(no title)

ambrop7 | 6 years ago

This is not right. The current rounding mode is not guaranteed to apply to integer to floating point conversions. Quoting C99, section 6.3.1.4, paragraph 2:

"When a value of integer type is converted to a real floating type, if the value being converted can be represented exactly in the new type, it is unchanged. If the value being converted is in the range of values that can be represented but cannot be represented exactly, the result is either the nearest higher or nearest lower representable value, chosen in an implementation-defined manner. If the value being converted is outside the range of values that can be represented, the behavior is undefined."

See it says implementation-defined manner, not according to the current rounding mode.

Test case:

    #pragma STDC FENV_ACCESS ON
    #include <stdio.h>
    #include <stdint.h>
    #include <fenv.h>

    int main()
    {
        fesetround(FE_DOWNWARD);
        printf("%f\n", (double)UINT64_MAX);
        fesetround(FE_UPWARD);
        printf("%f\n", (double)UINT64_MAX);
        return 0;
    }

    $ gcc -std=c99 -frounding-math x.c -lm
    $ ./a.out 
    18446744073709551616.000000
    18446744073709551616.000000
In both cases it rounded up.

discuss

order

ekimekim|6 years ago

I stand corrected, thanks! What a bizzare choice when floating point standards already have a well-defined system for determining how to round things.