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 imprime comme ceci: 12345678
Quel est le meilleur moyen de prévenir cela?
Vous pouvez utiliser printf()
avec %f
:
double dexp = 12345678; System.out.printf("dexp: %f\n", dexp);
Cela va imprimer dexp: 12345678.000000
. Si vous ne voulez pas la partie fractionnaire, utilisez
System.out.printf("dexp: %.0f\n", dexp);
Cela utilise le langage de spécification de format expliqué dans la documentation .
Le format toSsortingng()
par défaut utilisé dans votre code d’origine est épelé ici .
Cinq manières 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(Ssortingng[] 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 toPlainSsortingng(). System.out.println(new BigDecimal(myvalue).toPlainSsortingng()); System.out.println(); //Option 5, Ssortingng.format System.out.println(Ssortingng.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 explique: computerphile pourquoi 0.1
+ 0.2
égal à 0.30000000000001
?
En bref:
Si vous voulez vous débarrasser des problèmes de zéros et de parameters régionaux, 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:
Pourquoi d’autres réponses ne me convenaient pas:
Double.toSsortingng()
ou System.out.println
ou FloatingDecimal.toJavaFormatSsortingng
utilise des notations scientifiques si 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 6, sinon vous pouvez le coder en dur, mais cela se traduit par des zéros supplémentaires si vous avez moins de décimales. Exemple:
double myValue = 0.00000021d; Ssortingng.format("%.12f", myvalue); // Output: 0.000000210000
En utilisant setMaximumFractionDigits(0);
ou %.0f
vous supprimez toute précision décimale, ce qui est bien pour les entiers / longs, mais pas pour le double:
double myValue = 0.00000021d; System.out.println(Ssortingng.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 de la région. 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 langue locale FRANÇAISE vous permet d’obtenir un point pour le séparateur décimal, quel que soit le programme que vous utiliserez.
Pourquoi utiliser 340 alors pour setMaximumFractionDigits
?
Deux raisons:
setMaximumFractionDigits
accepte un entier, mais son implémentation a un maximum de chiffres autorisés pour 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 de la précision. Vous pouvez l’essayer avec DecimalFormat
. Avec cette classe, vous êtes très flexible dans l’parsing de vos chiffres.
Vous pouvez définir exactement le motif 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
J’ai une autre solution impliquant le toPlainSsortingng () de BigDecimal, mais cette fois-ci en utilisant le constructeur Ssortingng, recommandé dans javadoc:
ce constructeur est compatible avec les valeurs renvoyées par Float.toSsortingng et Double.toSsortingng. C’est généralement la méthode préférée pour convertir un float ou un double en BigDecimal, car il ne souffre pas de l’imprévisibilité du constructeur BigDecimal (double).
Cela ressemble à ceci dans sa forme la plus courte:
return new BigDecimal(myDouble.toSsortingng()).ssortingpTrailingZeros().toPlainSsortingng();
Pre Java 8, cela se traduit par “0.0” pour tous les doublons à valeur zéro, vous devrez donc append:
if (myDouble.doubleValue() == 0) return "0";
Les valeurs NaN et infinies doivent être vérifiées.
Le résultat final de toutes ces considérations:
public static Ssortingng doubleToSsortingng(Double d) { if (d == null) return null; if (d.isNaN() || d.isInfinite()) return d.toSsortingng(); // Pre Java 8, a value of 0 would yield "0.0" below if (d.doubleValue() == 0) return "0"; return new BigDecimal(d.toSsortingng()).ssortingpTrailingZeros().toPlainSsortingng(); }
Cela peut également être copié / collé pour fonctionner avec Float.
Cela fonctionnera tant que votre numéro est un nombre entier:
double dnexp = 12345678; System.out.println("dexp: " + (long)dexp);
Si la variable double a une précision après le point décimal, elle sera tronquée.
J’avais besoin de convertir certains doublons en valeurs monétaires et j’ai constaté que la plupart des solutions étaient acceptables, mais pas pour moi.
Le DecimalFormat
était finalement la voie pour moi, alors voici ce que j’ai fait:
public Ssortingng foo(double value) //Got here 6.743240136E7 or something.. { DecimalFormat formatter; if(value - (int)value > 0.0) formatter = new DecimalFormat("0.00"); // Here you can also deal with rounding if you wish.. else formatter = new DecimalFormat("0"); return formatter.format(value); }
Comme vous pouvez le voir, si le nombre est naturel, j’obtiens – disons – 20000000 au lieu de 2E7 (etc.) – sans point décimal.
Et si c’est décimal, je ne reçois que deux chiffres décimaux.
Le code suivant détecte si le nombre fourni est présenté en notation scientifique. Si c’est le cas, il est représenté dans une présentation normale avec un maximum de 25 chiffres.
static Ssortingng convertFromScientificNotation(double number) { // Check if in scientific notation if (Ssortingng.valueOf(number).toLowerCase().contains("e")) { System.out.println("The scientific notation number'" + number + "' detected, it will be converted to normal representation with 25 maximum fraction digits."); NumberFormat formatter = new DecimalFormat(); formatter.setMaximumFractionDigits(25); return formatter.format(number); } else return Ssortingng.valueOf(number); }
J’ai eu ce même problème dans mon code de production lorsque je l’utilisais comme une entrée de chaîne pour une fonction math.Eval () qui prend une chaîne comme “x + 20/50”
J’ai regardé des centaines d’articles … Au final, je suis allé avec ça à cause de la vitesse. Et parce que la fonction Eval allait la reconvertir dans son propre format numérique et que math.Eval () ne supportait pas le E-07 final renvoyé par les autres méthodes, et que tout élément dépassant 5 dp était trop détaillé pour mon application .
Ceci est maintenant utilisé dans le code de production pour une application qui a plus de 1000 utilisateurs …
double value = 0.0002111d; Ssortingng s = Double.toSsortingng(((int)(value * 100000.0d))/100000.0d); // Round to 5 dp s display as: 0.00021
Le compilateur Java / Kotlin convertit toute valeur supérieure à 9999999 (supérieure ou égale à 10 millions) en notation scientifique, c.-à-d. Notation Epsilion.
Ex: 12345678 est converti en 1.2345678E7
Utilisez ce code pour éviter la conversion automatique en notation scientifique:
fun setTotalSalesValue(Ssortingng total) { var valueWithoutEpsilon = total.toBigDecimal() /* Set the converted value to your android view using setText() function */ totalSalesValue.setText() = valueWithoutEpsilon.toPlainSsortingng() }
Je pense que tout le monde a eu la bonne idée, mais toutes les réponses n’étaient pas simples. Je peux voir cela comme un morceau de code très utile. Voici un extrait de ce qui fonctionnera:
System.out.println(Ssortingng.format("%.8f", EnterYourDoubleVariableHere));
le ".8"
est l’endroit où vous définissez le nombre de décimales que vous souhaitez afficher.
J’utilise Eclipse et cela n’a pas posé de problème.
J’espère que c’était utile. J’apprécierais n’importe quelle rétroaction!
Pour les valeurs entières représentées par un double
, vous pouvez utiliser ce code, qui est beaucoup plus rapide que les autres solutions.
public static Ssortingng doubleToSsortingng(final double d) { // check for integer, also see https://stackoverflow.com/a/9898613/868941 and // https://github.com/google/guava/blob/master/guava/src/com/google/common/math/DoubleMath.java if (isMathematicalInteger(d)) { return Long.toSsortingng((long)d); } else { // or use any of the solutions provided by others return Double.toSsortingng(d); } } // Java 8+ public static boolean isMathematicalInteger(final double d) { return SsortingctMath.rint(d) == d && Double.isFinite(d); }