Isso porque %d
espera um, int
mas você forneceu um flutuador.
Use %e
/ %f
/ %g
para imprimir o flutuador.
Por que 0 é impresso: O número de ponto flutuante é convertido em double
antes de enviar para printf
. O número 1234,5 em representação dupla em little endian é
00 00 00 00 00 4A 93 40
A %d
consome um número inteiro de 32 bits, portanto, um zero é impresso. (Como um teste, você printf("%d, %d\n", 1234.5f);
poderia obter na saída 0, 1083394560
.)
Quanto a por que o float
é convertido para double
, como o protótipo de printf é int printf(const char*, ...)
, de 6.5.2.2/7,
A notação de reticências em um declarador de protótipo de função faz com que a conversão do tipo de argumento pare após o último parâmetro declarado. As promoções de argumento padrão são executadas em argumentos finais.
e de 6.5.2.2/6,
Se a expressão que denota a função chamada tem um tipo que não inclui um protótipo, as promoções de inteiros são executadas em cada argumento e os argumentos que têm tipo float
são promovidos para double
. Eles são chamados de promoções de argumento padrão .
(Obrigado Alok por descobrir isso.)
printf
é uma função variada, e o padrão diz que para funções variadas, afloat
é convertidodouble
antes de passar.printf()
invoca o Comportamento Indefinido .Tecnicamente falando, não existe o
printf
, cada biblioteca implementa seu próprio e, portanto, seu método de tentar estudarprintf
o comportamento fazendo o que você está fazendo não será muito útil. Você pode estar tentando estudar o comportamento doprintf
em seu sistema e, nesse caso, deve ler a documentação e olhar o código-fonte para verprintf
se ele está disponível para sua biblioteca.Por exemplo, no meu Macbook, recebo a saída
1606416304
com o seu programa.Dito isto, quando você passa a
float
para uma função variável, ofloat
é passado como adouble
. Portanto, seu programa é equivalente a ter sido declaradoa
como umdouble
.Para examinar os bytes de a
double
, você pode ver esta resposta a uma pergunta recente aqui no SO.Vamos fazer isso:
Quando executo o programa acima, obtenho:
Então, os primeiros quatro bytes do
double
acabaram sendo 0, que pode ser o motivo pelo qual você obteve0
como saída de suaprintf
chamada.Para resultados mais interessantes, podemos mudar um pouco o programa:
Quando executo o programa acima no meu Macbook, obtenho:
Com o mesmo programa em uma máquina Linux, obtenho:
fonte
int
argumentos são passados em registros diferentes dosdouble
argumentos.printf
com%d
leva oint
argumento que é 42 e o segundo%d
provavelmente imprime lixo, pois não houve um segundoint
argumento.O
%d
especificador dizprintf
para esperar um inteiro. Portanto, os primeiros quatro (ou dois, dependendo da plataforma) bytes do float são interpretados como um inteiro. Se acontecer de eles serem zero, um zero é impressoA representação binária de 1234,5 é algo como
Com um compilador C que representa
float
na verdade como valores duplos IEEE754, os bytes seriam (se eu não me enganasse)Em um sistema Intel (x86) com pouco endianess (ou seja, o byte menos significativo vindo primeiro), essa sequência de bytes é revertida para que os primeiros quatro bytes sejam zero. Ou seja, o que
printf
imprime ...Consulte este artigo da Wikipedia para representação de ponto flutuante de acordo com IEEE754.
fonte
É por causa da representação de um flutuador em binário. A conversão para um número inteiro deixa com 0.
fonte
Porque você invocou um comportamento indefinido: você violou o contrato do método printf () mentindo para ele sobre seus tipos de parâmetro, então o compilador está livre para fazer o que quiser. Isso pode fazer com que a saída do programa seja "dksjalk é um ninnyhead !!!" e, tecnicamente, ainda estaria certo.
fonte
A razão é que essa
printf()
é uma função bastante idiota. Ele não verifica os tipos. Se você disser que o primeiro argumento é umint
(e é com isso que você está falando%d
), ele acredita em você e leva apenas os bytes necessários para umint
. Nesse caso, supondo que sua máquina use quatro bytesint
e oito bytesdouble
(ofloat
é convertido emdouble
internoprintf()
), os primeiros quatro bytes dea
serão apenas zeros e isso será impresso.fonte
Ele não converterá automaticamente float em inteiro. Porque ambos possuem formatos de armazenamento diferentes. Portanto, se você deseja converter, use o typecasting (int).
fonte
Como você também o marcou com C ++, este código faz a conversão como você provavelmente espera:
Resultado:
fonte
%d
é decimal%f
é flutuarveja mais destes aqui .
Você está obtendo 0 porque floats e inteiros são representados de forma diferente.
fonte
Você só precisa usar o especificador de formato apropriado (% d,% f,% s, etc.) Com o tipo de dados relevante (int, float, string, etc.).
fonte
Você quer% f não% d
fonte
ei, ele tinha que imprimir algo, então imprimiu um 0. Lembre-se que em C 0 está todo o resto!
fonte
Não é um número inteiro. Tente usar
%f
.fonte