En el programa dado, ¿por qué obtuve resultados diferentes para cada uno de los printf
s?
#include <stdio.h>
int main()
{
float c = 4.4e10;
printf("%f\n", c);
printf("%f\n", 4.4e10);
return 0;
}
Y muestra el siguiente resultado:
44000002048.000000
44000000000.000000
4.4e10
es unadouble
constante a la que se conviertefloat
en la inicializaciónc
pero que se mantiene como unadouble
cuando se pasa aprintf
. Sin embargo, es posible que también le interese saber que la adición de unf
sufijo hace que sea unafloat
constante: La impresión4.4e10f
mostrará el mismo valor que resulta de inicializaciónc
a4.4e10f
. Distinguirfloat
constantes dedouble
constantes puede ser importante para hacer un trabajo de calidad con aritmética de punto flotante.double
afloat
en el lenguaje C? ¿O desea saber qué valores resultan de la conversión, es decir, qué efectos tiene la conversión? ¿O algo mas?C
solíamos usarprintf("%f",x)
unfloat
yprintf("%lf",x)
para undouble
. ¿Cuándo cambiaron las cosas? ¿Y cómo se imprime explícitamente un (único)float
-printf("%hf",x)
??%lf
en printf es lo mismo que%f
. Afloat
en un argumento variable es convertido en adouble
por el compilador, al igual que ashort
se convierte en anint
.Respuestas:
A
float
es un tipo que contiene un número de coma flotante de 32 bits, mientras que la constante4.4e10
representa adouble
, que contiene un número de coma flotante de 64 bits (es decir, un número de coma flotante de doble precisión)Cuando se asigna
4.4e10
ac
, el valor4.4e10
no puede representarse con precisión (un error de redondeo en un parámetro llamado mantisa), y se almacena el valor más cercano posible (44000002048). Cuando se pasa aprintf
, se vuelve a promoverdouble
, incluido el error de redondeo.En el segundo caso, el valor es a
double
todo el tiempo, sin estrecharse ni ensancharse, y resulta que adouble
puede representar el valor exactamente.Si este es un comportamiento indeseable, puede declarar
c
como undouble
poco más de precisión (pero tenga en cuenta que eventualmente alcanzará los límites de precisión).fuente
En realidad, está imprimiendo los valores de dos tipos diferentes aquí.
En el primer caso, está asignando un valor a una variable de tipo
float
. La precisión de afloat
es de aproximadamente 6 o 7 dígitos decimales, por lo que, a menos que el valor pueda representarse exactamente, verá el valor más cercano que ese tipo puede representar.En el segundo caso, está pasando la constante
4.4e10
que tiene tipodouble
. Este tipo tiene alrededor de 16 dígitos decimales de precisión, y el valor está dentro de ese rango, por lo que se imprime el valor exacto.fuente