Comprender las conversiones implícitas para printf
El estándar C99 diferencia entre conversiones de tipo implícito y explícito (6.3 Conversiones). Supongo, pero no pude encontrar, que se realizan conversiones implícitas, cuando el tipo de destino es de mayor precisión que la fuente, y puede representar su valor. [Eso es lo que considero que pasa de INT a DOBLE]. Dado eso, miro el siguiente ejemplo:
#include <stdio.h> // printf
#include <limits.h> // for INT_MIN
#include <stdint.h> // for endianess
#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)
int main()
{
printf("sizeof(int): %lu\n", sizeof(int));
printf("sizeof(float): %lu\n", sizeof(float));
printf("sizeof(double): %lu\n", sizeof(double));
printf( IS_BIG_ENDIAN == 1 ? "Big" : "Little" ); printf( " Endian\n" );
int a = INT_MIN;
printf("INT_MIN: %i\n", a);
printf("INT_MIN as double (or float?): %e\n", a);
}
Me sorprendió mucho encontrar esa salida:
sizeof(int): 4
sizeof(float): 4
sizeof(double): 8
Little Endian
INT_MIN: -2147483648
INT_MIN as double (or float?): 6.916919e-323
Entonces, el valor flotante impreso es un número de coma flotante subnormal cerca del mínimo positivo subnormal mínimo mínimo 4.9406564584124654 × 10 ^ −324. Suceden cosas extrañas cuando comento los dos printf para endianess, obtengo otro valor para el doble:
#include <stdio.h> // printf
#include <limits.h> // for INT_MIN
#include <stdint.h> // for endianess
#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)
int main()
{
printf("sizeof(int): %lu\n", sizeof(int));
printf("sizeof(float): %lu\n", sizeof(float));
printf("sizeof(double): %lu\n", sizeof(double));
// printf( IS_BIG_ENDIAN == 1 ? "Big" : "Little" ); printf( " Endian\n" );
int a = INT_MIN;
printf("INT_MIN: %i\n", a);
printf("INT_MIN as double (or float?): %e\n", a);
}
salida:
sizeof(int): 4
sizeof(float): 4
sizeof(double): 8
INT_MIN: -2147483648
INT_MIN as double (or float?): 4.940656e-324
gcc --version: (Ubuntu 4.8.2-19ubuntu1) 4.8.2uname: x86_64 GNU / Linuxopciones del compilador donde: gcc -o x x.c -Wall -Wextra -std = c99 --pedanticY sí, allí donde hay una advertencia:x.c: In function ‘main’:
x.c:15:3: warning: format ‘%e’ expects argument of type ‘double’, but argument 2
has type ‘int’ [-Wformat=]
printf("INT_MIN as double (or float?): %e\n", a);
^
Pero todavía no puedo entender qué está sucediendo exactamente.
con poca endianess considero MIN_INT como: 00 ... 0001 y MIN_DBL (Subnormal) como 100..00 #, comenzando con la mantisa, seguido del exponente y concluyo con el#
como signo de bit.¿Es esta forma de aplicar el especificador de formato "% e" en un int, es una conversión implícita ?, una conversión reinterpretada?Estoy perdido, por favor enciéndeme.