262 votes

Comment imprimer une valeur double sans notation scientifique en utilisant Java ?

Je veux imprimer une valeur double en Java sans forme exponentielle.

double dexp = 12345678;
System.out.println("dexp: "+dexp);

Il montre cette notation E : 1.2345678E7 .

Je veux qu'il l'imprime comme ça : 12345678

Quelle est la meilleure façon d'éviter cela ?

269voto

Eric Leschinski Points 14289

Java empêche la notation E dans un double :

Cinq façons différentes de convertir un double en un nombre normal :

import java.math.BigDecimal;
import java.text.DecimalFormat;

public class Runner {
    public static void main(String[] args) {
        double myvalue = 0.00000021d;

        //Option 1 Print bare double.
        System.out.println(myvalue);

        //Option2, use decimalFormat.
        DecimalFormat df = new DecimalFormat("#");
        df.setMaximumFractionDigits(8);
        System.out.println(df.format(myvalue));

        //Option 3, use printf.
        System.out.printf("%.9f", myvalue);
        System.out.println();

        //Option 4, convert toBigDecimal and ask for toPlainString().
        System.out.print(new BigDecimal(myvalue).toPlainString());
        System.out.println();

        //Option 5, String.format 
        System.out.println(String.format("%.12f", myvalue));
    }
}

Ce programme imprime :

2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000

Qui ont tous la même valeur.

Protip : Si vous ne comprenez pas pourquoi ces chiffres aléatoires apparaissent au-delà d'un certain seuil dans la valeur double, cette vidéo l'explique : computerphile why does 0.1 + 0.2 égal 0.30000000000001 ?

http://youtube.com/watch?v=PZRI1IfStY0

0 votes

Il nous indique simplement comment imprimer la valeur double. Que faire si je veux la renvoyer en JSON ?

138voto

NPE Points 169956

Vous pourriez utiliser printf() con %f :

double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);

Ceci imprimera dexp: 12345678.000000 . Si vous ne voulez pas la partie fractionnaire, utilisez

System.out.printf("dexp: %.0f\n", dexp);

0 en %.0f signifie 0 place dans la partie fractionnaire, c'est-à-dire aucune partie fractionnaire. Si vous voulez imprimer la partie fractionnaire avec le nombre de décimales désiré, au lieu de 0, fournissez simplement le nombre comme ceci %.8f . Par défaut, la partie fractionnaire est imprimée jusqu'à 6 décimales.

Cette opération utilise le langage des spécificateurs de format expliqué dans le document documentation .

La valeur par défaut toString() utilisé dans votre code d'origine est expliqué en toutes lettres aquí .

1 votes

Mais il a montré dexp: 12345681.000000 Et en fait, après cela, je veux l'afficher sur ma page Web, où il s'affiche comme ceci 1.2345678E7 Y a-t-il un moyen pour que je puisse le stocker dans un double, par exemple 12345678 et d'une autre manière ?

1 votes

@despicable : Vous avez peut-être regardé l'ancienne version incomplète de la réponse. Essayez de recharger la page. Il devrait y avoir un paragraphe sur %.0f .

0 votes

@despicable vous pourriez stocker dexp comme un int afin de pouvoir l'utiliser facilement dans les deux sens.

119voto

JBE Points 998

En bref :

Si vous voulez vous débarrasser des zéros de fin et des problèmes de Locale, vous devez utiliser :

double myValue = 0.00000021d;

DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS

System.out.println(df.format(myValue)); // Output: 0.00000021

Explication :

Les autres réponses ne me convenaient pas :

  • Double.toString() o System.out.println o FloatingDecimal.toJavaFormatString utilise les notations scientifiques si le double est inférieur à 10^-3 ou supérieur ou égal à 10^7

  • En utilisant %f La précision décimale par défaut est de 6, sinon vous pouvez la coder en dur, mais cela entraîne l'ajout de zéros supplémentaires si vous avez moins de décimales. Exemple :

    double myValue = 0.00000021d;
    String.format("%.12f", myvalue); // Output: 0.000000210000
  • En utilisant setMaximumFractionDigits(0); o %.0f vous supprimez toute précision décimale, ce qui est bien pour les entiers/longs, mais pas pour les doubles :

    double myValue = 0.00000021d;
    System.out.println(String.format("%.0f", myvalue)); // Output: 0
    DecimalFormat df = new DecimalFormat("0");
    System.out.println(df.format(myValue)); // Output: 0
  • En utilisant DecimalFormat, vous êtes dépendant du local. En français, le séparateur décimal est une virgule, pas un point :

    double myValue = 0.00000021d;
    DecimalFormat df = new DecimalFormat("0");
    df.setMaximumFractionDigits(340);
    System.out.println(df.format(myvalue)); // Output: 0,00000021

    L'utilisation de la locale ENGLISH garantit l'obtention d'un séparateur de points pour les décimales, quel que soit le lieu d'exécution de votre programme.

Pourquoi utiliser 340 alors pour setMaximumFractionDigits ?

Pour deux raisons :

  • setMaximumFractionDigits accepte un nombre entier, mais son implémentation a un nombre maximum de chiffres autorisés de DecimalFormat.DOUBLE_FRACTION_DIGITS qui est égal à 340
  • Double.MIN_VALUE = 4.9E-324 Ainsi, avec 340 chiffres, vous êtes sûr de ne pas arrondir votre double et de perdre en précision.

0 votes

Quelle est votre opinion sur new BigDecimal(myvalue).toPlainString() D'après la description à [docs.oracle.com/javase/7/docs/api/java/math/](http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#toPlainString()) ), il n'est pas immédiatement évident de savoir comment il se comporte face à différents types de nombres, mais il élimine la notation scientifique.

4 votes

new BigDecimal(0.00000021d).toPlainString() sortie 0.0000002100000000000000010850153241148685623329583904705941‌​677093505859375 ce qui n'est pas ce que vous attendez...

0 votes

Une idée sur la façon d'utiliser votre réponse en scala ? probablement une question d'importations appropriées mais je suis nouveau ici.

28voto

Obl Tobl Points 3091

Vous pouvez l'essayer avec DecimalFormat . Avec cette classe, vous disposez d'une grande souplesse dans l'analyse de vos chiffres.
Vous pouvez définir exactement le modèle que vous souhaitez utiliser.
Dans votre cas par exemple :

double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678

8voto

NateS Points 1528

Cela fonctionne tant que votre nombre est un nombre entier :

double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);

Si la variable double a une précision après la virgule, elle sera tronquée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X