2

I'm trying to cast a double to an unsigned int. The double is guaranteed to be >= 0. Different compilers yield different results, though. Here is the example:

#include <stdio.h>

int main(int argc, char *argv[])
{
    double x = 5140528219;
    unsigned int y = (unsigned int) x;
    
    printf("%x\n", y);
    return 0;
}

Visual C seems to simply kill all bits >= 32 because it converts the double to 0x32663c5b. Gcc, however, seems to clip the whole number to UINT_MAX because the result is 0xffffffff.

Now there are some threads that mention compiler bugs in Visual C when it comes to converting double to unsigned int so I was wondering whether the behaviour I'm seeing here is a bug in Visual C as well or whether the conversion of double to unsigned int is just implementation dependent and thus undefined?

Any ideas?

My Visual C version is quite old (15.00.30729.01 for x64).

Andreas
  • 9,245
  • 9
  • 49
  • 97

1 Answers1

5

C 2018 6.3.1.4 1 says:

When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.

Therefore, if the value 5,140,528,219 is representable in unsigned int, it is the result. Otherwise, the C standard does not define the behavior.

In typical current C implementations, unsigned int is 32 bits or narrower, so it cannot represent numbers greater than 4,294,967,295. In such implementations, the behavior of converting 5,140,528,219 to unsigned int is not defined by the C standard.

Behavior around code like this has been observed to differ when performed at compile time versus execution time. When compiling, if a compiler deduces the value of the operand being converted, it may use its own arithmetic code to compute the result. If it cannot, it may generate an instruction that performs the conversion, and that conversion may generate a different result than the compiler’s built-in arithmetic. Thus, the behavior you observe may vary depending on whether optimization is enabled or not and depending on the context in which the conversion appears.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312