Pregunta

Estoy tratando de deshacerse de los símbolos innecesarios después separador decimal de mi doble valor. Lo estoy haciendo de esta manera:

DecimalFormat format = new DecimalFormat("#.#####");
value = Double.valueOf(format.format(41251.50000000012343));

Sin embargo, cuando ejecuta este código, se lanza:

java.lang.NumberFormatException: For input string: "41251,5"
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
    at java.lang.Double.valueOf(Double.java:447)
    at ...

Tal como lo veo, Double.valueOf() funciona muy bien con cadenas como "11.1", pero se ahoga con cadenas como "11,1". ¿Cómo trabajo alrededor de esto? ¿Hay una manera más elegante entonces algo así como

Double.valueOf(format.format(41251.50000000012343).replaceAll(",", "."));

¿Hay una manera de anular el valor por defecto del separador decimal clase DecimalFormat? ¿Alguna otra idea?

¿Fue útil?

Solución

Por

  

deshacerse de los símbolos innecesarios después separador decimal de mi doble valor

es lo que realmente quiere decir que desea redondear a, por ejemplo, el quinto decimal? Entonces sólo tiene que utilizar

value = Math.round(value*1e5)/1e5;

(por supuesto también puede Math.floor(value*1e5)/1e5 si realmente desea que los otros dígitos cortado)

Otros consejos

El problema es que su formato decimal convierte el valor a una cadena localizada. Supongo que su separador decimal predeterminado para su ubicación es con un ','. Esto sucede a menudo con los lugares franceses o de otras partes del mundo.

Básicamente lo que hay que hacer es crear su fecha formateada con el '' separador de manera Double.valueOf puede leerlo. Tal como indican los comentarios, puede utilizar el mismo formato para analizar el valor, así en lugar de utilizar Double.valueOf.

DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
symbols.setDecimalSeparator('.');
DecimalFormat format = new DecimalFormat("#.#####", symbols);
value = format.parse(format.format(41251.50000000012343));

El hecho de que sus usos formato de cadenas . como separador decimal, mientras que la excepción se queja de puntos , a un problema de configuración regional; es decir DecimalFormat está utilizando una configuración regional diferente para formatear el número de Espera Double.valueOf.

En general, se debe construir un NumberFormat basado en una configuración regional específica.

Locale myLocale = ...;
NumberFormat f = NumberFormat.getInstance(myLocale);

A partir de los JavaDocs de DecimalFormat :

  

Para obtener un NumberFormat para una configuración regional específica, incluyendo la configuración regional predeterminada, llamar a uno de los métodos de fábrica de NumberFormat, tales como getInstance (). En general, no llame a los constructores DecimalFormat directamente, ya que los métodos de fábrica NumberFormat pueden volver subclases distintas de DecimalFormat.

Sin embargo como puntos BalusC fuera , intentar formatear un doble como una cadena y luego analizar la parte posterior cadena de la doble es un muy mal olor código. Sospecho que se trata de cuestiones en las que se espera un número de precisión fija decimal (por ejemplo, una cantidad monetaria), pero está ejecutando en problemas debido a doble es un número de coma flotante, lo que significa que muchos valores (como 0.1) no se puede expresado precisamente como un doble / flotador. Si este es el caso, la forma correcta de manejar un número de precisión decimal fijo es usar un BigDecimal .

Uso Locale.getDefault() para obtener su separador decimal del sistema que también se puede configurar. No se puede tener a distintos agentes de separación al mismo tiempo, ya que el otro es entonces por lo general se utiliza como seprator por miles: 2.001.000,23 <=> 2,001,000.23

Para el ',' en lugar del '.', que tendría que cambiar la configuración regional.

Para el número de decimales, el uso setMaximumFractionDigits(int newValue).

Para el resto, consulte el Javadoc .

Parece que tu uso local una coma "" como un decimal separation.To obtener el "" como separador decimal, tendrá que declarar:

DecimalFormat dFormat =new DecimalFormat("#.#", new DecimalFormatSymbols(Locale.ENGLISH));

No se puede cambiar la representación interna de double / Double de esa manera.

Si desea cambiar la representación (humana), si prefieres algo String. Por lo tanto, deje que Double#valueOf() distancia y utilice el resultado de String DecimalFormat#format() en su presentación. Si alguna vez quieres hacer cálculos con ella, siempre se puede convertir de nuevo a un Double real utilizando DecimalFormat y Double#valueOf().

Por cierto, como por su quejan Estoy tratando de deshacerse de los símbolos innecesarios después separador decimal de mi doble valor , ¿estás al tanto de la parte interna de números de punto flotante ? Huele un poco como que está utilizando dobles sin formato en la capa de presentación y que no se dio cuenta de que con la interfaz de usuario promedio que sólo puede presentarlos utilizando DecimalFormat sin la necesidad de convertir de nuevo a Double.

Algo relacionado con esto, pero no una respuesta a la pregunta: trate de cambiar a BigDecimal en lugar de dobles y flotadores. Estaba teniendo un montón de problema con las comparaciones de ese tipo y ahora que soy bueno para ir con BigDecimal.

La solución real es: no utilice números de punto flotante para cualquier cosa que necesita ser contados con precisión:

  • Si se trata de la moneda, no utilice un doble número de dólares, utilizar un número entero de centavos.
  • Si se trata de horas de tiempo y necesidad de contar con cuartos de horas y cada 10 minutos, utilizar un número entero de minutos.

Un número de coma flotante es casi siempre una aproximación de algún valor real. Son adecuados para mediciones y cálculo de cantidades físicas (arriba un grado de precisión) y para artefactos estadísticos.

El engañar alrededor con el redondeo de punto flotante a un número de dígitos es un olor código:. Que es un desperdicio y que nunca puede estar seguro de que su código funcionará correctamente en todos los casos

Mi función de código:

 private static double arrondi(double number){
         DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
         symbols.setDecimalSeparator('.');
         DecimalFormat format = new DecimalFormat("#.#####", symbols);
         return Double.valueOf(format.format(number));
     }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top