Saltar al contenido

Convierte float a double sin perder precisión

Sé libre de compartir nuestros tutoriales y códigos con otro, ayúdanos a hacer crecer esta comunidad.

Solución:

no es que seas Realmente obteniendo precisión adicional: es que el flotador no representaba con precisión el número que estaba buscando originalmente. El doble es representar con precisión el flotador original; toString está mostrando los datos “extra” que ya estaban presentes.

Por ejemplo (y estos números no son correctos, solo estoy inventando cosas) suponga que tiene:

float f = 0.1F;
double d = f;

Entonces el valor de f podría ser exactamente 0.100000234523. d tendrá exactamente el mismo valor, pero cuando lo convierte a un string “confiará” en que es preciso con una precisión mayor, por lo que no se redondeará tan pronto, y verá los “dígitos adicionales” que ya estaban allí, pero ocultos para usted.

Cuando te conviertes en un string y viceversa, está terminando con un valor doble que está más cerca del string valor que el flotador original, pero eso solo es bueno Si realmente crees que el string el valor es lo que realmente querías.

¿Está seguro de que float/double son los tipos apropiados para usar aquí en lugar de BigDecimal? Si está tratando de usar números que tienen valores decimales precisos (por ejemplo, dinero), entonces BigDecimal es un tipo IMO más apropiado.

Encuentro que convertir a la representación binaria es más fácil de entender este problema.

float f = 0.27f;
double d2 = (double) f;
double d3 = 0.27d;

System.out.println(Integer.toBinaryString(Float.floatToRawIntBits(f)));
System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d2)));
System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d3)));

Puede ver que el flotante se expande al doble agregando 0 al final, pero que la representación doble de 0.27 es ‘más precisa’, de ahí el problema.

   111110100010100011110101110001
11111111010001010001111010111000100000000000000000000000000000
11111111010001010001111010111000010100011110101110000101001000

Esto se debe al contrato de Float.toString(float)que dice en parte:

¿Cuántos dígitos se deben imprimir para la parte fraccionaria? […]? Debe haber al menos un dígito para representar la parte fraccionaria, y más allá de eso, tantos, pero solo tantos,más dígitos que sean necesarios para distinguir de forma única el valor del argumento de los valores adyacentes de tipo flotante. Es decir, suponga que x es el valor matemático exacto representado por la representación decimal producida por este método para un argumento finito distinto de cero f. Entonces f debe ser el valor flotante más cercano a x; o, si dos valores flotantes están igualmente cerca de x, entonces f debe ser uno de ellos y el bit menos significativo del significado de f debe ser 0.

Valoraciones y reseñas

No se te olvide comunicar este escrito si te valió la pena.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *