Estoy tratando de emitir un double a un unsigned int . Se garantiza que el double sea >= 0. Sin embargo, diferentes compiladores producen resultados diferentes. Aquí está el ejemplo:
#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 parece simplemente eliminar todos los bits >= 32 porque convierte el double en 0x32663c5b. Gcc, sin embargo, parece recortar el número completo a UINT_MAX porque el resultado es 0xffffffff.
Ahora, hay algunos subprocesos que mencionan errores del compilador en Visual C cuando se trata de convertir double a unsigned int , por lo que me preguntaba si el comportamiento que veo aquí también es un error en Visual C o si la conversión de double a unsigned int ¿depende solo de la implementación y, por lo tanto, no está definido?
¿Algunas ideas?
Mi versión de Visual C es bastante antigua (15.00.30729.01 para x64).
C 2018 6.3.1.4 1 dice:
Cuando un valor finito de tipo flotante real se convierte en un tipo entero que no sea
_Bool,la parte fraccionaria se descarta (es decir, el valor se trunca hacia cero). Si el valor de la parte integral no puede ser representado por el tipo entero, el comportamiento es indefinido.
Por lo tanto, si el valor 5,140,528,219 es representable en unsigned int , es el resultado. De lo contrario, el estándar C no define el comportamiento.
En las implementaciones típicas de C actuales, unsigned int tiene 32 bits o menos, por lo que no puede representar números mayores que 4,294,967,295. En tales implementaciones, el estándar C no define el comportamiento de convertir 5,140,528,219 a unsigned int .
Se ha observado que el comportamiento en torno a un código como este difiere cuando se realiza en tiempo de compilación en comparación con el tiempo de ejecución. Al compilar, si un compilador deduce el valor del operando que se está convirtiendo, puede usar su propio código aritmético para calcular el resultado. Si no puede, puede generar una instrucción que realice la conversión, y esa conversión puede generar un resultado diferente al de la aritmética integrada del compilador. Por lo tanto, el comportamiento que observe puede variar según si la optimización está habilitada o no y según el contexto en el que aparece la conversión.