No programa fornecido, por que obtive resultados diferentes para cada um dos printf
s?
#include <stdio.h>
int main()
{
float c = 4.4e10;
printf("%f\n", c);
printf("%f\n", 4.4e10);
return 0;
}
E mostra a seguinte saída:
44000002048.000000
44000000000.000000
4.4e10
é umadouble
constante que é convertidafloat
na inicialização de,c
mas mantida comodouble
quando passada paraprintf
. No entanto, você também pode querer saber que adicionar umf
sufixo o torna umafloat
constante: a impressão4.4e10f
mostrará o mesmo valor resultante da inicializaçãoc
para4.4e10f
. Distinguirfloat
constantes dedouble
constantes pode ser importante para realizar um trabalho de qualidade com aritmética de ponto flutuante.double
parafloat
ocorre no idioma C? Ou você deseja saber quais valores resultam da conversão, ou seja, quais efeitos a conversão tem? Ou alguma outra coisa?C
que usamosprintf("%f",x)
para umfloat
eprintf("%lf",x)
para umdouble
. Quando as coisas mudaram? E como imprimir explicitamente um (único)float
-printf("%hf",x)
??%lf
em printf é a mesma coisa que%f
. Afloat
em um argumento variável é convertido em adouble
pelo compilador, assim como ashort
é convertido em umaint
.Respostas:
A
float
é um tipo que contém um número de ponto flutuante de 32 bits, enquanto a constante4.4e10
representa adouble
, que contém um número de ponto flutuante de 64 bits (ou seja, um número de ponto flutuante de dupla precisão)Quando você atribui
4.4e10
ac
, o valor4.4e10
não pode ser representado com precisão (um erro de arredondamento em um parâmetro chamado mantissa) e o valor mais próximo possível (44000002048) é armazenado. Quando é passado paraprintf
, é promovido de volta paradouble
, incluindo o erro de arredondamento.No segundo caso, o valor é
double
o tempo todo, sem estreitar e alargar, e acontece que adouble
pode representar exatamente o valor.Se este é um comportamento indesejável, você pode declarar
c
comodouble
para um pouco mais de precisão (mas cuidado que você ainda vai bater limites de precisão eventualmente).fonte
Você está realmente imprimindo os valores de dois tipos diferentes aqui.
No primeiro caso, você está atribuindo um valor a uma variável do tipo
float
. A precisão de afloat
é aproximadamente 6 ou 7 dígitos decimais, portanto, a menos que o valor possa ser representado exatamente, você verá o valor mais próximo que pode ser representado por esse tipo.No segundo caso, você está passando a constante
4.4e10
que tem o tipodouble
. Esse tipo tem cerca de 16 dígitos decimais de precisão e o valor está dentro desse intervalo, portanto, o valor exato é impresso.fonte