parse how float example convertir convert conversion castear java floating-point double

java - how - Convierte float a double sin perder precisión



how to parse double to float (9)

Tengo un flotador primitivo y lo necesito como un doble primitivo. Simplemente lanzar el flotador al doble me da una precisión extra extraña. Por ejemplo:

float temp = 14009.35F; System.out.println(Float.toString(temp)); // Prints 14009.35 System.out.println(Double.toString((double)temp)); // Prints 14009.349609375

Sin embargo, si en lugar de emitir, dejo el float como una cadena y analizo la cadena como un doble, obtengo lo que quiero:

System.out.println(Double.toString(Double.parseDouble(Float.toString(temp)))); // Prints 14009.35

¿Hay una mejor manera de ir a String y viceversa?


¿Esto funciona?

float flt = 145.664454; Double dbl = 0.0; dbl += flt;


Encontré la siguiente solución:

public static Double getFloatAsDouble(Float fValue) { return Double.valueOf(fValue.toString()); }

Si usa float y double en lugar de Float y Double use lo siguiente:

public static double getFloatAsDouble(float value) { return Double.valueOf(Float.valueOf(value).toString()).doubleValue(); }


Encuentro que la conversión a la representación binaria es más fácil de comprender 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)));

Puedes ver que el flotador se expande al doble sumando 0s al final, pero que la doble representación 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 como sean necesarios para distinguir de manera única el valor del argumento de los valores adyacentes de tipo flotante. Es decir, supongamos 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 son igualmente cercanos a x, entonces f debe ser uno de ellos y el bit menos significativo del significado de f debe ser 0.


Hoy me he encontrado con este problema y no he podido utilizar refactor en BigDecimal, porque el proyecto es realmente enorme. Sin embargo, encontré solución usando

Float result = new Float(5623.23) Double doubleResult = new FloatingDecimal(result.floatValue()).doubleValue()

Y esto funciona

Tenga en cuenta que al llamar a result.doubleValue () se devuelve 5623.22998046875

Pero al llamar a doubleResult.doubleValue () se devuelve correctamente 5623.23

Pero no estoy del todo seguro de si es una solución correcta.


Los flotadores, por naturaleza, son imprecisos y siempre tienen "problemas" de redondeo. Si la precisión es importante, entonces podría considerar refaccionar su aplicación para usar Decimal o BigDecimal.

Sí, los flotantes son computacionalmente más rápidos que los decimales debido a la compatibilidad con el procesador. Sin embargo, ¿quieres rápido o preciso?


No es que realmente obtengas precisión adicional, es que el flotador no representaba con precisión el número que pretendías originalmente. El doble representa el flotador original con precisión; toString muestra los datos "adicionales" que ya estaban presentes.

Por ejemplo (y estos números no son correctos, solo estoy inventando cosas) tu apoyo fue:

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 convierta en una cadena, "confiará" que es preciso con mayor precisión, por lo que no se redondeará tan pronto, y verá los "dígitos adicionales" que eran Ya está allí, pero escondido de ti.

Cuando conviertes una cadena y regresas, terminas con un valor doble que está más cerca del valor de la cadena que el float original, pero eso solo es bueno si realmente crees que el valor de la cadena es lo que realmente deseas.

¿Estás 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 de IMO más apropiado.


Para información, esto se incluye en el Ítem 48 - Evite flotante y doble cuando se requieren valores exactos, de Effective Java 2nd edition de Joshua Bloch. Este libro está repleto de cosas buenas y definitivamente vale la pena echarle un vistazo.


Use un BigDecimal lugar de float / double . Hay muchos números que no se pueden representar como punto flotante binario (por ejemplo, 0.1 ). Por lo tanto, siempre debe redondear el resultado a una precisión conocida o utilizar BigDecimal .

Consulte http://en.wikipedia.org/wiki/Floating_point para obtener más información.