round - redondear decimales en java netbeans




¿Cómo formatear bien los números flotantes a Cadena sin decimal innecesario 0? (15)

Aquí hay dos maneras de lograrlo. Primero, la forma más corta (y probablemente mejor):

public static String formatFloatToString(final float f)
  {
  final int i=(int)f;
  if(f==i)
    return Integer.toString(i);
  return Float.toString(f);
  }

Y aquí está la manera más larga y probablemente peor:

public static String formatFloatToString(final float f)
  {
  final String s=Float.toString(f);
  int dotPos=-1;
  for(int i=0;i<s.length();++i)
    if(s.charAt(i)=='.')
      {
      dotPos=i;
      break;
      }
  if(dotPos==-1)
    return s;
  int end=dotPos;
  for(int i=dotPos+1;i<s.length();++i)
    {
    final char c=s.charAt(i);
    if(c!='0')
      end=i+1;
    }
  final String result=s.substring(0,end);
  return result;
  }

Un doble de 64 bits puede representar un entero +/- 2 53 exactamente

Dado este hecho, elijo usar un tipo doble como un solo tipo para todos mis tipos, ya que mi entero más grande es sin signo de 32 bits.

Pero ahora tengo que imprimir estos pseudo enteros, pero el problema es que también se mezclan con los dobles reales.

Entonces, ¿cómo puedo imprimir estos dobles muy bien en Java?

He intentado String.format("%f", value) , que está cerca, excepto que obtengo muchos ceros finales para valores pequeños.

Aquí hay un ejemplo de salida de %f

232.00000000
0.18000000000
1237875192.0
4.5800000000
0.00000000
1.23450000

Lo que quiero es:

232
0.18
1237875192
4.58
0
1.2345

Claro que puedo escribir una función para recortar esos ceros, pero eso es una gran pérdida de rendimiento debido a la manipulación de cadenas. ¿Puedo hacerlo mejor con otro código de formato?

EDITAR

Las respuestas de Tom E. y Jeremy S. son inaceptables, ya que ambas se redondean arbitrariamente a dos decimales. Por favor, comprenda el problema antes de responder.

Editar 2

Tenga en cuenta que String.format(format, args...) depende de la configuración regional (consulte las respuestas a continuación).


Aquí hay una respuesta que realmente funciona (combinación de respuestas diferentes aquí)

public static String removeTrailingZeros(double f)
{
    if(f == (int)f) {
        return String.format("%d", (int)f);
    }
    return String.format("%f", f).replaceAll("0*$", "");
}

Este hará bien el trabajo, sé que el tema es viejo, pero estuve luchando con el mismo problema hasta que llegué a esto. Espero que alguien lo encuentre útil.

    public static String removeZero(double number) {
        DecimalFormat format = new DecimalFormat("#.###########");
        return format.format(number);
    }

Esto es lo que se me ocurrió:

  private static String format(final double dbl) {
    return dbl % 1 != 0 ? String.valueOf(dbl) : String.valueOf((int) dbl);
  }

Simple un forro, solo se lanza a int si realmente se necesita


Mis 2 centavos:

if(n % 1 == 0) {
    return String.format(Locale.US, "%.0f", n));
} else {
    return String.format(Locale.US, "%.1f", n));
}

No, no importa.

La pérdida de rendimiento debido a la manipulación de la cadena es cero.

Y aquí está el código para recortar el final después de %f

private static String trimTrailingZeros(String number) {
    if(!number.contains(".")) {
        return number;
    }

    return number.replaceAll("\\.?0*$", "");
}

Respuesta tardía pero ...

Usted dijo que elige almacenar sus números con el tipo doble . Creo que esta podría ser la raíz del problema porque lo obliga a almacenar enteros en dobles (y por lo tanto perder la información inicial sobre la naturaleza del valor). ¿Qué hay acerca de almacenar sus números en instancias de la clase Number (superclase de Double y Integer) y confiar en el polimorfismo para determinar el formato correcto de cada número?

Sé que puede que no sea aceptable refactorizar una parte completa de su código debido a eso, pero podría producir la salida deseada sin código / conversión / análisis adicional.

Ejemplo:

import java.util.ArrayList;
import java.util.List;

public class UseMixedNumbers {

    public static void main(String[] args) {
        List<Number> listNumbers = new ArrayList<Number>();

        listNumbers.add(232);
        listNumbers.add(0.18);
        listNumbers.add(1237875192);
        listNumbers.add(4.58);
        listNumbers.add(0);
        listNumbers.add(1.2345);

        for (Number number : listNumbers) {
            System.out.println(number);
        }
    }

}

Producirá la siguiente salida:

232
0.18
1237875192
4.58
0
1.2345

Sé que este es un hilo muy antiguo ... Pero creo que la mejor manera de hacerlo es la siguiente:

public class Test {

    public static void main(String args[]){
        System.out.println(String.format("%s something",new Double(3.456)));
        System.out.println(String.format("%s something",new Double(3.456234523452)));
        System.out.println(String.format("%s something",new Double(3.45)));
        System.out.println(String.format("%s something",new Double(3)));
    }
}

Salida:

3.456 something
3.456234523452 something
3.45 something
3.0 something

El único problema es el último donde no se elimina .0. Pero si eres capaz de vivir con eso, entonces esto funciona mejor. % .2f lo redondeará a los últimos 2 dígitos decimales. También lo hará DecimalFormat. Si necesita todos los lugares decimales pero no los ceros finales, entonces esto funciona mejor.


Tenga en cuenta que String.format(format, args...) depende de la configuración regional, ya que se formatea utilizando la configuración regional predeterminada del usuario, es decir, probablemente con comas e incluso espacios dentro, como 123 456,789 o 123,456.789 , que puede no ser exactamente lo que esperar.

Es posible que prefiera utilizar String.format((Locale)null, format, args...) .

Por ejemplo,

    double f = 123456.789d;
    System.out.println(String.format(Locale.FRANCE,"%f",f));
    System.out.println(String.format(Locale.GERMANY,"%f",f));
    System.out.println(String.format(Locale.US,"%f",f));

huellas dactilares

123456,789000
123456,789000
123456.789000

y esto es lo que hará String.format(format, args...) en diferentes países.

EDITAR Ok, ya que ha habido una discusión sobre formalidades:

    res += stripFpZeroes(String.format((Locale) null, (nDigits!=0 ? "%."+nDigits+"f" : "%f"), value));
    ...

protected static String stripFpZeroes(String fpnumber) {
    int n = fpnumber.indexOf('.');
    if (n == -1) {
        return fpnumber;
    }
    if (n < 2) {
        n = 2;
    }
    String s = fpnumber;
    while (s.length() > n && s.endsWith("0")) {
        s = s.substring(0, s.length()-1);
    }
    return s;
}

Utilice un DecimalFormat y setMinimumFractionDigits(0)


String s = "1.210000";
while (s.endsWith("0")){
    s = (s.substring(0, s.length() - 1));
}

Esto hará que la cadena deje caer los relaves 0-s.


String s = String.valueof("your int variable");
while (g.endsWith("0") && g.contains(".")) {
    g = g.substring(0, g.length() - 1);
    if (g.endsWith("."))
    {
        g = g.substring(0, g.length() - 1);
    }
}

if (d == Math.floor(d)) {
    return String.format("%.0f", d);
} else {
    return Double.toString(d);
}

new DecimalFormat("#.##").format(1.199); //"1.2"

Como se señaló en los comentarios, esta no es la respuesta correcta a la pregunta original.
Dicho esto, es una forma muy útil de dar formato a los números sin ceros finales innecesarios.


public static String fmt(double d) {
    String val = Double.toString(d);
    String[] valArray = val.split("\\.");
    long valLong = 0;
    if(valArray.length == 2){
        valLong = Long.parseLong(valArray[1]);
    }
    if (valLong == 0)
        return String.format("%d", (long) d);
    else
        return String.format("%s", d);
}

Tuve que usar esta causa d == (long)d me estaba dando una violación en el informe de sonar







double