Comment imprimer une double valeur sans notation scientifique en utilisant Java?
Je veux imprimer une double valeur en Java sans forme exponentielle.
double dexp = 12345678;
System.out.println("dexp: "+dexp);
Il montre cette notation E: 1.2345678E7
.
Je veux l'imprimer comme ceci: 12345678
Quelle est la meilleure façon d'éviter cela?
12 réponses
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 par défaut toString()
utilisé dans votre code d'origine est défini ici.
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.println(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 sont tous de la même valeur.
Protip: si vous êtes confus quant à la raison pour laquelle ces chiffres aléatoires apparaissent au-delà d'un certain seuil dans la double valeur, cette vidéo explique: computerphile pourquoi 0.1
+0.2
égal 0.30000000000001
?
En bref:
Si vous voulez vous débarrasser des zéros de fin et des problèmes de paramètres 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.toString()
ouSystem.out.println
ouFloatingDecimal.toJavaFormatString
utilise des notations scientifiques si un double est inférieur à 10^-3 ou supérieure ou égale à 10^7 -
En utilisant
%f
, la précision décimale par défaut est 6, sinon vous pouvez la coder en dur, mais il en résulte des zéros supplémentaires ajoutés si vous avoir moins de décimales. Exemple:double myValue = 0.00000021d; String.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 double: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 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 des paramètres régionaux anglais vous permet d'obtenir un point pour le séparateur décimal, où que votre programme s'exécute.
Pourquoi utiliser 340 alors pour setMaximumFractionDigits
?
Deux raisons:
-
setMaximumFractionDigits
accepte un entier, mais son implémentation a un nombre maximal de chiffres autorisé de {[12] } qui est égal à 340 - {[13] } donc, avec 340 chiffres, vous êtes sûr de ne pas arrondir votre double et perdre de la précision.
Vous pouvez l'essayer avec DecimalFormat
. Avec cette classe, vous êtes très flexible dans l'analyse de vos numéros.
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
J'ai une autre solution impliquant toPlainString () de BigDecimal, mais cette fois en utilisant le constructeur de chaîne, qui est recommandé dans javadoc:
Ce constructeur est compatible avec les valeurs renvoyées par Float.toString et Double.toString. C'est généralement le moyen préféré de convertir un float ou un double en BigDecimal, car il ne souffre pas de l'imprévisibilité du constructeur BigDecimal(double).
Il ressemble à ceci dans son plus court forme:
return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();
Pré Java 8, il en résulte " 0.0 " pour tous les Doubles à valeur nulle, vous devez donc ajouter:
if (myDouble.doubleValue() == 0)
return "0";
Les valeurs NaN et infinies doivent être vérifiées en sus.
Le résultat final de toutes ces considérations:
public static String doubleToString(Double d) {
if (d == null)
return null;
if (d.isNaN() || d.isInfinite())
return d.toString();
// Pre Java 8, a value of 0 would yield "0.0" below
if (d.doubleValue() == 0)
return "0";
return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString();
}
Cela peut également être copié / collé pour fonctionner correctement avec Float.
Cela fonctionnera 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 décimale, elle la tronquera.
J'avais besoin de convertir quelques doubles en valeurs monétaires et j'ai constaté que la plupart des solutions étaient correctes, mais pas pour moi.
Le {[1] } a finalement été le chemin pour moi, alors voici ce que j'ai fait:
public String 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, je reçois - disons-20000000 au lieu de 2E7 (etc.) - sans point décimal.
Et si c'est décimal, Je n'obtiens 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 String convertFromScientificNotation(double number) {
// Check if in scientific notation
if (String.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 String.valueOf(number);
}
, j'ai eu ce même problème dans mon code quand je l'utilise comme une entrée de chaîne de maths.Eval () fonction qui prend une chaîne comme "x + 20/50"
J'ai regardé des centaines d'articles... En fin de compte, je suis allé avec cela à cause de la vitesse. Et parce que la fonction Eval allait le convertir en son propre format de nombre éventuellement et en mathématiques.Eval () n'a pas pris en charge le E-07 final que d'autres méthodes ont renvoyé, et tout ce qui dépasse 5 dp était trop détaillé pour mon application de toute façon.
Ceci est maintenant utilisé dans le code de production pour une application qui compte plus de 1 000 utilisateurs...
double value = 0.0002111d;
String s = Double.toString(((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 ie. Notation Epsilion.
Ex: 12345678 est converti en 1. 2345678E7
Utilisez ce code pour éviter la conversion automatique en notation scientifique:
fun setTotalSalesValue(String total) {
var valueWithoutEpsilon = total.toBigDecimal()
/* Set the converted value to your android view using setText() function */
totalSalesValue.setText() = valueWithoutEpsilon.toPlainString()
}
Je pense que tout le monde avait la bonne idée, mais toutes les réponses n'étaient pas simples. Je peux voir que c'est un morceau de code très utile. Voici un extrait de ce qui va fonctionner:
System.out.println(String.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 fonctionné.
J'espère que cela a été utile. J'apprécierais tout commentaire!
Pour les valeurs entières représenté par un double
, vous pouvez utiliser ce code, qui est beaucoup plus rapide que les autres solutions.
public static String doubleToString(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.toString((long)d);
} else {
// or use any of the solutions provided by others
return Double.toString(d);
}
}
// Java 8+
public static boolean isMathematicalInteger(final double d) {
return StrictMath.rint(d) == d && Double.isFinite(d);
}