Eso es porque %d
espera un int
pero le proporcionaste un flotador.
Utilice %e
/ %f
/ %g
para imprimir el flotador.
Por qué se imprime 0: el número de coma flotante se convierte a double
antes de enviar a printf
. El número 1234.5 en representación doble en little endian es
00 00 00 00 00 4A 93 40
A %d
consume un entero de 32 bits, por lo que se imprime un cero. (Como prueba, printf("%d, %d\n", 1234.5f);
podría obtener la salida 0, 1083394560
).
En cuanto a por qué float
se convierte a double
, como es el prototipo de printf int printf(const char*, ...)
, desde 6.5.2.2/7,
La notación de puntos suspensivos en un declarador de prototipo de función hace que la conversión del tipo de argumento se detenga después del último parámetro declarado. Las promociones de argumentos predeterminadas se realizan en argumentos finales.
y de 6.5.2.2/6,
Si la expresión que denota la función llamada tiene un tipo que no incluye un prototipo, las promociones de enteros se realizan en cada argumento y float
se promueven los argumentos que tienen tipo double
. Estos se denominan promociones de argumentos predeterminados .
(Gracias Alok por descubrir esto).
printf
es una función variadica, y el estándar dice que para funciones variadas, afloat
se convierte adouble
antes de pasar.printf()
invoca un comportamiento indefinido .Técnicamente hablando no existe el
printf
, cada biblioteca implementa la suya propia y, por lo tanto, su método para tratar de estudiarprintf
el comportamiento haciendo lo que está haciendo no será de mucha utilidad. Podría estar intentando estudiar el comportamiento deprintf
en su sistema, y si es así, debería leer la documentación y mirar el código fuente para verprintf
si está disponible para su biblioteca.Por ejemplo, en mi Macbook, obtengo la salida
1606416304
con su programa.Habiendo dicho eso, cuando pasas a
float
a una función variada,float
se pasa como adouble
. Entonces, su programa equivale a haber declaradoa
comodouble
.Para examinar los bytes de a
double
, puede ver esta respuesta a una pregunta reciente aquí en SO.Vamos a hacer eso:
Cuando ejecuto el programa anterior, obtengo:
Entonces, los primeros cuatro bytes
double
resultaron ser 0, que puede ser la razón por la que obtuviste0
como resultado de tuprintf
llamada.Para obtener resultados más interesantes, podemos cambiar un poco el programa:
Cuando ejecuto el programa anterior en mi Macbook, obtengo:
Con el mismo programa en una máquina Linux, obtengo:
fuente
int
argumentos se pasan en registros diferentes a losdouble
argumentos.printf
with%d
toma elint
argumento que es 42 y el segundo%d
probablemente imprime basura ya que no había un segundoint
argumento.El
%d
especificador diceprintf
que espere un número entero. Entonces, los primeros cuatro (o dos, dependiendo de la plataforma) bytes del flotante se interpretan como un número entero. Si resultan ser cero, se imprime un ceroLa representación binaria de 1234.5 es algo así como
Con un compilador de C que representa en
float
realidad como valores dobles IEEE754, los bytes serían (si no me equivoco)En un sistema Intel (x86) con poca endianess (es decir, el byte menos significativo viene primero), esta secuencia de bytes se invierte para que los primeros cuatro bytes sean cero. Es decir, lo que
printf
imprime ...Consulte este artículo de Wikipedia para ver la representación de punto flotante de acuerdo con IEEE754.
fuente
Es por la representación de un flotador en binario. La conversión a un número entero lo deja con 0.
fuente
Porque invocó un comportamiento indefinido: violó el contrato del método printf () mintiéndole sobre sus tipos de parámetros, por lo que el compilador es libre de hacer lo que le plazca. Podría hacer que la salida del programa "dksjalk es un tonto!" y técnicamente aún estaría bien.
fuente
La razón es que
printf()
es una función bastante tonta. No comprueba los tipos en absoluto. Si dice que el primer argumento es unint
(y esto es lo que está diciendo%d
), le cree y solo toma los bytes necesarios para unint
. En este caso, asumiendo que su máquina usa cuatro bytesint
y ocho bytesdouble
(elfloat
se convierte en undouble
interiorprintf()
), los primeros cuatro bytesa
serán solo ceros, y esto se imprime.fuente
No convertirá automáticamente flotante en entero. Porque ambos tienen diferente formato de almacenamiento. Entonces, si desea convertir, use (int) typecasting.
fuente
Dado que también lo etiquetó con C ++, este código realiza la conversión como probablemente espera:
Salida:
fuente
%d
es decimal%f
es flotarvea más de estos aquí .
Obtienes 0 porque los números flotantes y enteros se representan de manera diferente.
fuente
Solo necesita usar el especificador de formato apropiado (% d,% f,% s, etc.) con el tipo de datos relevante (int, float, string, etc.).
fuente
Quieres% f no% d
fuente
oye, tenía que imprimir algo así que imprimió un 0. ¡Recuerda que en C 0 está todo lo demás!
fuente
No es un número entero. Intente usar
%f
.fuente