Comment puis-je tronquer un double à seulement deux décimales en Java?

93

Par exemple, j'ai la variable 3.545555555, que je voudrais tronquer à seulement 3,54.

Johnny
la source
18
Ce n'est PAS un doublon. Tronquer et arrondir sont deux choses complètement différentes.
markthegrea
D'accord, je ne sais pas pourquoi cela est signalé comme duplicata.
Bassinator

Réponses:

144

Si vous le souhaitez à des fins d'affichage, utilisez java.text.DecimalFormat:

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

Si vous en avez besoin pour les calculs, utilisez java.lang.Math:

 Math.floor(value * 100) / 100;
Bozho
la source
50
Cela n'affichera pas un 3,545555555 tronqué à 3,54, mais arrondi à 3,55. DecimalFormat.setRoundingMode () doit être défini sur RoundingMode.FLOOR;
Christian García
9
cela ne fonctionne pas pour moi Math.floor (9,62 * 100) / 100 donne 9,61
Mani
4
Utiliser floorpour tronquer ne fonctionne que pour les valeurs positives.
Dev
3
@ ChristianGarcía La troncature est correctement effectuée avec, RoundingMode.DOWNcomme RoudingMode.FLOORtoujours, des arrondis vers l'infini négatif.
Dev
46
DecimalFormat df = new DecimalFormat(fmt);
df.setRoundingMode(RoundingMode.DOWN);
s = df.format(d);

Vérifiez disponible RoundingModeet DecimalFormat.

Cédric Dubourg
la source
Ne répond pas à la question, qui demandait une troncature plutôt qu'un arrondi.
Basil Bourque
8
@BasilBourque RoundingMode.DOWN est une troncature. Comparez avec d'autres réponses qui recommandent à tort les fonctions de plancher (le plancher tronque uniquement les nombres positifs), cela fonctionne correctement pour les valeurs positives et négatives.
Dev
1
@Dev je suis corrigé. Je vois maintenant que DOWNcela a effectivement l'effet de troncature pour les nombres positifs et négatifs. Comme vu dans le tableau des exemples dans le doc .
Basil Bourque
23

Bit Old Forum, Aucune des réponses ci-dessus n'a fonctionné pour les valeurs positives et négatives (je veux dire pour le calcul et simplement pour tronquer sans arrondir). À partir du lien Comment arrondir un nombre à n décimales dans Java

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);
    }
}

Cette méthode a bien fonctionné pour moi.

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));

Résultats :

0.00
9.62
9.62
9.62
9.62
9.99
-9.99
-9.00
Mani
la source
c'est la réponse plus évolutive pour plus de cas de test
diego matos - keke
retourne un nouveau BigDecimal (x) .setScale (numberofDecimals, RoundingMode.DOWN) .doubleValue ();
Shimon Doodkin le
semble arrondi est comme ce que vous vouliez dire: docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html
Shimon Doodkin
9

Notons d' abord que doubleest une fraction binaire et ne pas vraiment avoir décimales.

Si vous avez besoin de décimales, utilisez a BigDecimal, qui a une setScale()méthode de troncature, ou utilisez DecimalFormatpour obtenir un String.

Michael Borgwardt
la source
7

Si, pour une raison quelconque, vous ne souhaitez pas utiliser a, BigDecimalvous pouvez convertir votre doubleen un intpour le tronquer.

Si vous souhaitez tronquer à l' emplacement des Unes :

  • il suffit de lancer int

Vers la dixième place:

  • multiplier par dix
  • cast à int
  • renvoyer vers double
  • et divisez par dix.

Hundreths place

  • multipliez et divisez par 100 etc.

Exemple:

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;
}

Dans cet exemple, decimalPlacesserait le nombre de places PASSÉ les endroit où vous voulez aller, donc 1 arrondissent à la dixième place, 2 aux centièmes , et ainsi de suite (0 tours au ceux lieu, et un négatif aux dizaines , etc.)

Tarvis
la source
3
C'est une terrible solution générale. La multiplication et la distribution finiront par jeter des données et aboutiront à ce qui sont effectivement des nombres aléatoires si unroundedNumberc'est assez gros. Cela peut fonctionner pour l'exemple de la question, mais une solution générale devrait fonctionner pour tout double.
blm
4

Le formatage sous forme de chaîne et la conversion en double, je pense, vous donneront le résultat souhaité.

La valeur double ne sera pas round (), floor () ou ceil ().

Une solution rapide pour cela pourrait être:

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

Vous pouvez utiliser sValue à des fins d'affichage ou newValue pour le calcul.

Jao Assy
la source
1
Il arrondit pour moi à la valeur la plus proche. Par exemple: 0,018 est converti en 0,02 lorsque j'ai fait cela.
karan patel
3

Peut Math.floor(value * 100) / 100- être ? Attention, les valeurs comme 3.54peuvent ne pas être exactement représentées par un double.

Vlad
la source
3

Vous pouvez utiliser l'objet de classe NumberFormat pour accomplir la tâche.

// 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
Shams Rushdi
la source
3

3,545555555 pour obtenir 3,54. Essayez de suivre pour cela:

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

    df.setRoundingMode(RoundingMode.FLOOR);

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

Cela donnera = 3,54!

Ankush G
la source
1

Voici la méthode que j'utilise:

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

Cela peut également être fait:

a=Math.floor(a*100) / 100;
Mitchell Hynes
la source
0

Peut-être suivant:

double roundTwoDecimals(double d) { 
      DecimalFormat twoDForm = new DecimalFormat("#.##"); 
      return Double.valueOf(twoDForm.format(d));
}  
Ritesh Mengji
la source
Voir les autres réponses. Vous ne pouvez pas le faire de manière fiable si la réponse doit être représentée en virgule flottante.
Marquis de Lorne
0

Une vérification rapide consiste à utiliser la méthode Math.floor. J'ai créé une méthode pour vérifier un double pour deux décimales ou moins ci-dessous:

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;
}
chris31389
la source
-1

J'ai une version légèrement modifiée de Mani .

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));

}

Production:

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
HolyLance
la source
-2

Cela a fonctionné pour moi:

double input = 104.8695412  //For example

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

//result == 104.87

J'aime personnellement cette version car elle effectue en fait l'arrondi numériquement, plutôt qu'en la convertissant en chaîne (ou similaire), puis en la formatant.

Arc-en-ciel975
la source
1
La question initiale concerne la troncature et non l'arrondi. De plus, convertir un double en long ne fonctionnera pas du tout si le double est suffisamment grand.
blm
-2
//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

Eh bien, cela peut être un peu gênant, mais je pense que cela peut résoudre votre problème :)

user5251903
la source
Ce code fait le travail, mais il n'est pas élégant et ses performances sont médiocres. Cela peut convenir dans les projets scolaires, mais ce n'est certainement pas une solution que quelqu'un utiliserait en production pour n'importe quel système, à moins que vous ne souhaitiez avoir des maux de tête plus tard.
cbaldan