Arrondissez un double à 2 décimales

Si la valeur est 200.3456 , il doit être formaté à 200.34 . Si c’est 200 , alors ça devrait être 200.00 .

    Voici un utilitaire qui arrondit (au lieu de tronquer ) un nombre de décimales double à spécifié.

    Par exemple:

     round(200.3456, 2); // returns 200.35 

    Version originale; attention à cela

     public static double round(double value, int places) { if (places < 0) throw new IllegalArgumentException(); long factor = (long) Math.pow(10, places); value = value * factor; long tmp = Math.round(value); return (double) tmp / factor; } 

    Cela se décompose mal dans les virages avec soit un nombre très élevé de décimales (par exemple round(1000.0d, 17) ) ou une grande partie entière (par exemple round(90080070060.1d, 9) ). Merci à Sloin de l' avoir signalé.

    J'ai utilisé ce qui précède pour arrondir les doubles "pas trop gros" à 2 ou 3 décimales pendant des années (par exemple pour nettoyer le temps en secondes à des fins de journalisation: 27.987654321987 -> 27.99). Mais je pense qu’il est préférable de l’éviter, car des méthodes plus fiables sont disponibles, avec un code plus propre.

    Donc, utilisez ceci à la place

    (Adapté de cette réponse de Louis Wasserman et celle de Sean Owen .)

     public static double round(double value, int places) { if (places < 0) throw new IllegalArgumentException(); BigDecimal bd = new BigDecimal(value); bd = bd.setScale(places, RoundingMode.HALF_UP); return bd.doubleValue(); } 

    Notez que HALF_UP est le mode d'arrondissement "couramment enseigné à l'école". Parcourez la documentation RoundingMode , si vous pensez avoir besoin d'autre chose comme l'arrondi des banquiers .

    Bien sûr, si vous préférez, vous pouvez intégrer ce qui précède dans un document unique:
    new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()

    Et dans tous les cas

    Rappelez-vous toujours que les représentations en virgule flottante utilisant float et double sont inexactes . Par exemple, considérons ces expressions:

     999199.1231231235 == 999199.1231231236 // true 1.03 - 0.41 // 0.6200000000000001 

    Pour plus de précision, vous voulez utiliser BigDecimal . Et pendant ce temps, utilisez le constructeur qui prend un Ssortingng, jamais celui qui prend le double. Par exemple, essayez d'exécuter ceci:

     System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41))); System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41"))); 

    Quelques excellentes lectures sur le sujet:

    • Item 48: "Evitez le float et double si des réponses exactes sont requirejses" dans Effective Java (2nd ed) par Joshua Bloch
    • Ce que chaque programmeur doit savoir sur l'arithmétique en virgule flottante

    Si vous souhaitez un formatage de chaîne au lieu de (ou en plus) des nombres ssortingctement arrondis, consultez les autres réponses.

    Spécifiquement, notez que round(200, 0) renvoie 200.0 . Si vous voulez sortir " 200.00 ", vous devez d'abord arrondir puis formater le résultat pour la sortie (ce qui est parfaitement expliqué dans la réponse de Jesper ).

    Si vous voulez simplement imprimer un double avec deux chiffres après la virgule, utilisez quelque chose comme ceci:

     double value = 200.3456; System.out.printf("Value: %.2f", value); 

    Si vous souhaitez avoir le résultat dans une Ssortingng au lieu d’être imprimé sur la console, utilisez Ssortingng.format() avec les mêmes arguments:

     Ssortingng result = Ssortingng.format("%.2f", value); 

    Ou utilisez la classe DecimalFormat :

     DecimalFormat df = new DecimalFormat("####0.00"); System.out.println("Value: " + df.format(value)); 

    Je pense que c’est plus facile:

     double time = 200.3456; DecimalFormat df = new DecimalFormat("#.##"); time = Double.valueOf(df.format(time)); System.out.println(time); // 200.35 

    Notez que cela fera l’arrondi pour vous, pas seulement le formatage.

    Le plus simple serait de faire un tour comme celui-ci;

     double val = ....; val = val*100; val = Math.round(val); val = val /100; 

    Si val commence à 200.3456 puis passe à 20034.56, il est arrondi à 20035, puis nous le divisons pour obtenir 200.34.

    Si vous voulez toujours arrondir, nous pouvons toujours tronquer en convertissant en int:

     double val = ....; val = val*100; val = (double)((int) val); val = val /100; 

    Cette technique fonctionnera dans la plupart des cas car elle risque de déborder si le double est très élevé (positif ou négatif). mais si vous savez que vos valeurs seront dans une plage appropriée, cela devrait fonctionner pour vous.

    Veuillez utiliser les maths Apache commons :

     Precision.round(10.4567, 2) 
     function Double round2(Double val) { return new BigDecimal(val.toSsortingng()).setScale(2,RoundingMode.HALF_UP).doubleValue(); } 

    Notez le toSsortingng () !!!!

    C’est parce que BigDecimal convertit la forme binary exacte du double !!!

    Ce sont les différentes méthodes suggérées et leurs cas d’échec.

     // Always Good! new BigDecimal(val.toSsortingng()).setScale(2,RoundingMode.HALF_UP).doubleValue() Double val = 260.775d; //EXPECTED 260.78 260.77 - WRONG - new BigDecimal(val).setScale(2,RoundingMode.HALF_UP).doubleValue() Double val = 260.775d; //EXPECTED 260.78 260.77 - TRY AGAIN - Math.round(val * 100.d) / 100.0d Double val = 256.025d; //EXPECTED 256.03d 256.02 - OOPS - new DecimalFormat("0.00").format(val) // By default use half even, works if you change mode to half_up Double val = 256.025d; //EXPECTED 256.03d 256.02 - FAIL - (int)(val * 100 + 0.5) / 100.0; 
     double value= 200.3456; DecimalFormat df = new DecimalFormat("0.00"); System.out.println(df.format(value)); 

    Si vous voulez vraiment le même double, mais arrondi comme vous le souhaitez, vous pouvez utiliser BigDecimal, par exemple

     new BigDecimal(myValue).setScale(2, RoundingMode.HALF_UP).doubleValue(); 
     double d = 28786.079999999998; Ssortingng str = Ssortingng.format("%1.2f", d); d = Double.valueOf(str); 

    Arrondir un double n’est généralement pas ce que l’on veut. Au lieu de cela, utilisez Ssortingng.format() pour le représenter dans le format souhaité.

    Pour deux chiffres d’arrondi. Très simple, vous mettez à jour la variable au lieu de simplement afficher les objectives de DecimalFormat.

    x = Math.floor(x * 100) / 100;

     value = (int)(value * 100 + 0.5) / 100.0; 

    Dans votre question, il semble que vous vouliez éviter d’arrondir les chiffres aussi? Je pense que .format () arrondira les nombres en utilisant un demi-mi
    Donc, si vous voulez arrondir, 200.3456 devrait être 200.35 pour une précision de 2. mais dans votre cas, si vous voulez juste le premier 2 et ensuite défaussez le rest?

    Vous pouvez le multiplier par 100, puis le lancer dans un int (ou prendre la parole du nombre) avant de diviser par 100 à nouveau.

     200.3456 * 100 = 20034.56; (int) 20034.56 = 20034; 20034/100.0 = 200.34; 

    Vous pourriez avoir des problèmes avec des nombres vraiment très importants près de la frontière. Dans ce cas, convertir en chaîne et en sous-chaîne fonctionnerait tout aussi facilement.