2012-01-05 15 views
9

Sé cómo formatear un doble para mantener solo los decimales disponibles (DP), hasta un cierto número de DP. Este ejemplo mantiene hasta 4 DP.Formatea un doble para omitir el ".0" innecesario y nunca redondear

double d = 1.0; 
    DecimalFormat df = new DecimalFormat("#.####"); 
    System.out.print(df.format(d)); // returns "1" 

    double d = 1.23; 
    DecimalFormat df = new DecimalFormat("#.####"); 
    System.out.print(df.format(d)); // returns "1.23" 

    double d = 1.2345678; 
    DecimalFormat df = new DecimalFormat("#.####"); 
    System.out.print(df.format(d)); // returns "1.2346", rounding off: bad! 

Ahora quiero números enteros p. Ej. 1.0 para devolver "1" sin el innecesario .0, y el carácter de formato # proporciona esa funcionalidad. ¿Pero cómo me aseguro de que el número nunca se redondea? ¿Hay alguna otra manera que no sea una cadena arbitrariamente larga de # como "#.###########################################"?

O debo utilizar la conversión por defecto de doble cadena a, y truncar el ".0" si aparece al final:

String s = "" + d; 
    if(s.substring(s.length()-2).equals(".0")) { 
     s=s.substring(0, s.length()-2); 
    } 

Ambas formas parece terriblemente torpe.

Respuesta

14

utilizo el siguiente

double d = 
String s = (long) d == d ? "" + (long) d : "" + d; 

si necesita doble en vez de dos. (Personalmente me gustaría evitar el uso de la envoltura si es posible)

Double d = 
String s = d.longValue() == d ? "" + d.longValue() : "" + d; 
+0

+1 para Wow ... !! – RanRag

+2

incluso si el compilador puede optimizarlo avay Creo que es mejor estilo para usar String.valueOf (x) en lugar de "" + x – rurouni

+0

@rurouni Muchos estarían de acuerdo contigo. Sin embargo, prefiero un código más simple porque es más rápido de leer y escribir, ahorrándole tiempo a todos. Si el rendimiento es un problema, todavía no utilizaría valueOf ya que crea objetos. –

-1

Usted podría utilizar Double.doubleToLongBits() y extraer el exponente y la mantisa. Desde api doc:

Bit 63 (el bit que es seleccionado por la máscara 0x8000000000000000L) representa el signo del número en coma flotante. Los bits 62-52 (los bits que se seleccionan mediante la máscara 0x7ff0000000000000L) representan el exponente . Los bits 51-0 (los bits seleccionados por la máscara 0x000fffffffffffffL) representan el significado (a veces llamado mantisa) del número de coma flotante.

El exponente se puede usar para determinar el número de dígitos significativos, pero siempre tendrá que redondear en algún punto ya que algunos valores binarios de doulbe serán infinitos en decimales.

Para una representación binaria puede simplemente utilizar la mantisa y poner el punto decimal en la posición correcta (relleno con ceros si es necesario.

+0

La mayoría de los valores decimales no enteros no se pueden representar como números binarios, p. 0.1. por lo que se aproximará a 0.10000000000000000000001 o similar. Tal vez deberías pensar en qué tan grande puede ser el error de la representación mostrada (o cuántas digis significativas quedan en el cálculo anterior) – rurouni

+0

Lo siento, me perdí que la pregunta era solo sobre números enteros, pero lo dejaré en caso de que alguien pueda úsalo ;-) – rurouni

1

Por defecto, el modo de redondeo está a la DecimalFormat. Puede establecer diferentes formatos de redondeo como por su requiremnet usando setRoundingMode() método Código

de ejemplo para establecer el modo de redondeo

double d = 1.2345678; 
     DecimalFormat df = new DecimalFormat("#.####"); 
     df.setRoundingMode(RoundingMode.DOWN); 
     System.out.print(df.format(d));//result 1.2345 because of rounding down 
+0

"cómo me aseguro de que el número nunca se redondea" –

+0

@ Jean-FrançoisCorbett: no se puede a menos que uses un sistema numérico binario o de cualquier base 2^n (p. ej. octal o hexadecimal) – rurouni

+0

Claro, lo sé acerca de la aritmética de punto flotante, pero ese no es el punto de la pregunta. ¿Cómo me aseguro de que la representación de la cadena del número no se redondee a otra cosa que no sea '" "+ d'? Esta respuesta * explícitamente * lo redondea, que es exactamente lo contrario de lo que pregunté. –

Cuestiones relacionadas