¿Cómo puedo truncar un doble a solo dos decimales en Java? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Por ejemplo, tengo la variable 3.545555555, que me gustaría truncar a solo 3.54.

Author: Johnny, 2011-10-13

15 answers

Si desea que para fines de visualización, utilice java.text.DecimalFormat:

 new DecimalFormat("#.##").format(dblVar);

Si lo necesita para los cálculos, use java.lang.Math:

 Math.floor(value * 100) / 100;
 105
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-19 17:20:41
DecimalFormat df = new DecimalFormat(fmt);
df.setRoundingMode(RoundingMode.DOWN);
s = df.format(d);

De Verificación disponible RoundingMode y DecimalFormat.

 36
Author: Cedric Dubourg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-14 19:55:36

Foro poco antiguo, Ninguna de las respuestas anteriores funcionó tanto para valores positivos como negativos ( me refiero al cálculo y solo para truncar sin Redondear). Desde el Cómo redondear un número a n decimales en Java enlace

private static BigDecimal truncateDecimal(double x,int numberofDecimals)
{
    if ( x > 0) {
        return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_FLOOR);
    } else {
        return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_CEILING);
    }
}

Este método funcionó bien para mí .

System.out.println(truncateDecimal(0, 2));
    System.out.println(truncateDecimal(9.62, 2));
    System.out.println(truncateDecimal(9.621, 2));
    System.out.println(truncateDecimal(9.629, 2));
    System.out.println(truncateDecimal(9.625, 2));
    System.out.println(truncateDecimal(9.999, 2));
    System.out.println(truncateDecimal(-9.999, 2));
    System.out.println(truncateDecimal(-9.0, 2));

Resultados:

0.00
9.62
9.62
9.62
9.62
9.99
-9.99
-9.00
 14
Author: Mani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:37

Tenga en cuenta primero que un doublees una fracción binaria y realmente no tiene decimales.

Si necesita decimales, use un BigDecimal, que tiene un método setScale() para el truncamiento, o use DecimalFormat para obtener un String.

 7
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-12 22:52:20

Si, por cualquier razón, no quieres usar un BigDecimal puedes lanzar tu double a un int para truncarlo.

Si quieres truncar a los lugar:

  • simplemente lanzar a int

A los Décimos lugar:

  • multiplicar por diez
  • fundido a int
  • volver a double
  • y dividir por diez.

Centésimos lugar

  • multiplicar y dividir por 100 sucesivamente.

Ejemplo:

static double truncateTo( double unroundedNumber, int decimalPlaces ){
    int truncatedNumberInt = (int)( unroundedNumber * Math.pow( 10, decimalPlaces ) );
    double truncatedNumber = (double)( truncatedNumberInt / Math.pow( 10, decimalPlaces ) );
    return truncatedNumber;
}

En este ejemplo, decimalPlaces sería el número de lugares MÁS ALLÁ de los lugares a los que desea ir, por lo que 1 redondearía al lugar décimas, 2 al lugar centésimas, y así sucesivamente (0 redondea al lugar ones, y uno negativo a las decenas, etc.)

 5
Author: Tarvis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-18 03:44:30

Tal vez Math.floor(value * 100) / 100? Tenga en cuenta que los valores como 3.54 pueden no estar exactamente representados con un double.

 4
Author: Vlad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-12 22:49:25

Puede usar el objeto de clase NumberFormat para realizar la tarea.

// Creating number format object to set 2 places after decimal point
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);            
nf.setGroupingUsed(false);

System.out.println(nf.format(precision));// Assuming precision is a double type variable
 3
Author: Rushdi Shams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-13 01:12:30

3.545555555 para obtener 3.54. Prueba lo siguiente para esto:

    DecimalFormat df = new DecimalFormat("#.##");

    df.setRoundingMode(RoundingMode.FLOOR);

    double result = new Double(df.format(3.545555555);

Esto dará = 3.54!

 2
Author: Ankush G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-02 06:08:15

Formatear como una cadena y convertir de nuevo a double creo que le dará el resultado que desea.

El valor double no será round(), floor() o ceil().

Una solución rápida para ello podría ser:

 String sValue = (String) String.format("%.2f", oldValue);
 Double newValue = Double.parseDouble(sValue);

Puede utilizar el sValue para fines de visualización o el newValue para el cálculo.

 2
Author: Jao Assy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-27 02:44:22

Aquí está el método que uso:

double a=3.545555555; // just assigning your decimal to a variable
a=a*100;              // this sets a to 354.555555
a=Math.floor(a);      // this sets a to 354
a=a/100;              // this sets a to 3.54 and thus removing all your 5's

Esto también se puede hacer:

a=Math.floor(a*100) / 100;
 1
Author: Mitchell Hynes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-07 17:55:09

Tal vez siguiendo:

double roundTwoDecimals(double d) { 
      DecimalFormat twoDForm = new DecimalFormat("#.##"); 
      return Double.valueOf(twoDForm.format(d));
}  
 0
Author: Ritesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-12 22:51:37

Una comprobación rápida es usar las matemáticas.método de piso. He creado un método para comprobar un doble para dos o menos lugares decimales a continuación:

public boolean checkTwoDecimalPlaces(double valueToCheck) {

    // Get two decimal value of input valueToCheck 
    double twoDecimalValue = Math.floor(valueToCheck * 100) / 100;

    // Return true if the twoDecimalValue is the same as valueToCheck else return false
    return twoDecimalValue == valueToCheck;
}
 0
Author: chris31389,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-05 17:18:18
//if double_v is 3.545555555
String string_v= String.valueOf(double_v);
int pointer_pos = average.indexOf('.');//we find the position of '.'
string_v.substring(0, pointer_pos+2));// in this way we get the double with only 2 decimal in string form
double_v = Double.valueOf(string_v);//well this is the final result

Bueno, esto puede ser un poco incómodo, pero creo que puede resolver su problema:)

 0
Author: user5251903,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-07 13:04:03

Tengo una versión ligeramente modificada de Mani's.

private static BigDecimal truncateDecimal(final double x, final int numberofDecimals) {
    return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_DOWN);
}

public static void main(String[] args) {
    System.out.println(truncateDecimal(0, 2));
    System.out.println(truncateDecimal(9.62, 2));
    System.out.println(truncateDecimal(9.621, 2));
    System.out.println(truncateDecimal(9.629, 2));
    System.out.println(truncateDecimal(9.625, 2));
    System.out.println(truncateDecimal(9.999, 2));
    System.out.println(truncateDecimal(3.545555555, 2));

    System.out.println(truncateDecimal(9.0, 2));
    System.out.println(truncateDecimal(-9.62, 2));
    System.out.println(truncateDecimal(-9.621, 2));
    System.out.println(truncateDecimal(-9.629, 2));
    System.out.println(truncateDecimal(-9.625, 2));
    System.out.println(truncateDecimal(-9.999, 2));
    System.out.println(truncateDecimal(-9.0, 2));
    System.out.println(truncateDecimal(-3.545555555, 2));

}

Salida:

0.00
9.62
9.62
9.62
9.62
9.99
9.00
3.54
-9.62
-9.62
-9.62
-9.62
-9.99
-9.00
-3.54
 -1
Author: user1189617,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:05

Esto funcionó para mí:

double input = 104.8695412  //For example

long roundedInt = Math.round(input * 100);
double result = (double) roundedInt/100;

//result == 104.87

Personalmente me gusta esta versión porque en realidad realiza el redondeo numérico, en lugar de convertirlo en una cadena (o similar) y luego formatearlo.

 -1
Author: Rainbow975,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-14 07:06:01