2010-08-09 35 views
6

Dado el siguiente código, esperaría que devuelva "float = 32000.0001". Pero, en cambio, devuelve "float = 32000.0".Redondeo en java Float.parseFloat

System.out.println("float = "+Float.parseFloat("32000.0001")); 

¿Hay algo que pueda hacer para prevenir/controlar el redondeo? Quiero que se devuelva el valor completo sin redondeo.

Respuesta

7

Un flotador tiene solo 24 bits de precisión, que es insuficiente para mantener el número de dígitos en su valor. El redondeo no se debe al análisis sino al tamaño del número. Debe usar un doble si necesita coma flotante o usar BigDecimal si necesita precisión arbitraria.

1

Si las decimales son de su interés, yo fuertemente recomendaría usar BigDecimal en su lugar.

Tal como es, no es del todo claro para mí (sin verificar) si el problema es el análisis sintáctico de una cadena o el formateo de nuevo a una cadena.

EDIT: En este caso sospecho firmemente que es el redondeo en el análisis ... ya que float tiene sólo 7 (garantizados) dígitos significativos y que está tratando de preservar 9.

+0

me rompió la línea única en varias líneas y se lo pasó por el depurador. El problema parece estar en el análisis sintáctico. Parece que Float.parseFloat está redondeando a "32000.0" – Shane

+0

@Shane: Aún asumes que el depurador te está mostrando el valor exacto, sospecho. –

+0

cambiando a BigDecimal solucionado mis problemas con decimales – jeff

0

Si se quiere evitar el redondeo, use BigDecimal. Los tipos primitivos float y double son más rápidos pero no pueden representar muchos valores decimales comunes.

0

Flotadores y dobles son limitados. Solo son capaces de representar con precisión porciones fraccionarias de números como una suma de dos fracciones de base. La parte fraccionaria puede ser plenamente representada como la suma de algunas series como:

1/2 + 0/4 + 1/8 + 1/16 + ...

Por desgracia hay un gran número de frecuencia números usados ​​que nunca pueden ser plenamente representados, como:

1/3, 1/7, 1/9, 5/11, etc.

debe tener en cuenta si el número se puede representar con precisión antes de preocuparse redondeando Si este tipo de precisión es de extrema importancia, entonces debe buscar una solución no flotante o no doble.

Hay bibliotecas de decimales binarias que realizarán con precisión tales cálculos. Tienden a ser más lentos de calcular, porque no hay hardware especializado para acelerar sus cálculos. Además, tienden a ocupar más memoria, porque básicamente estás almacenando una lista de dígitos.

Después de que pueda representar el número que desea con los detalles que desea, entonces una solución de redondeo es simple. Las probabilidades son que ni siquiera necesitará una solución de redondeo; porque, la razón principal por la que intentas redondear en este caso se debe a que el flotador no puede representar tu valor correctamente.

2

Debe tener mucho cuidado al usar el punto flotante al escribir software.
Ciertos números decimales no tienen representaciones exactas de base 2, es una cosa a tener en cuenta. 0.1, 0.01, 0.001 son algunos ejemplos. Entonces para representar estos números en la base 2 se necesita redondear.

Otro problema es que está tratando con un conjunto finito de bits para representar números y puede experimentar otros errores de redondeo. Además, cuanto más te alejas de 0, más números hay que no se pueden representar con exactitud y, por lo tanto, se produce el redondeo.

Existen otros problemas. La mayoría se mencionan en el documento a continuación. Para un tratado formal, vea esto: http://www.scribd.com/doc/5836/What-Every-Computer-Scientist-Should-Know-About-FloatingPoint-Arithmetic

No utilice flotadores donde necesita saber un número exacto.

1

Como otros señalan, float tiene precisión insuficiente para mantener el resultado completo. El constructor BigDecimal(double) es exacta, por lo que es una forma práctica de ver la representación:

System.out.println(new BigDecimal(32000.0001f)); // as float 
System.out.println(new BigDecimal(32000.0001d)); // as double 

que muestra esto:

32000 
32000.00010000000111176632344722747802734375 
+0

Si está analizando el texto, debe usar el constructor 'BigDecimal (String)'; dará una precisión aún mejor –

+0

@Sanjay Manohar: Correcto; esto es meramente una forma conveniente de comparar las representaciones decimales de los valores correspondientes de 'float' y' double'. Esta calculadora es una alternativa: http://babbage.cs.qc.edu/IEEE-754/Decimal.html – trashgod