Un double 64 bits peut représenter un entier +/- 2 53 exactement
Compte tenu de ce fait, je choisis d'utiliser un type double comme type unique pour tous mes types, car mon plus grand entier n'est pas signé 32 bits.
Mais maintenant, je dois imprimer ces pseudo entiers, mais le problème est qu'ils sont également mélangés avec des doubles réels.
Alors, comment puis-je imprimer ces doubles bien en Java?
J'ai essayé String.format("%f", value)
, ce qui est proche, sauf que j'obtiens beaucoup de zéros de fin pour les petites valeurs.
Voici un exemple de sortie de %f
232.00000000 0,18000000000 1237875192.0 4.5800000000 0.00000000 1.23450000
Ce que je veux c'est:
232 0,18 1237875192 4,58 0 1,2345
Bien sûr, je peux écrire une fonction pour couper ces zéros, mais cela représente beaucoup de perte de performances en raison de la manipulation de String. Puis-je faire mieux avec un autre code de format?
ÉDITER
Les réponses de Tom E. et Jeremy S. sont inacceptables car elles arrondissent toutes les deux arbitrairement à 2 décimales. Veuillez comprendre le problème avant de répondre.
EDIT 2
Veuillez noter que cela String.format(format, args...)
dépend des paramètres régionaux (voir les réponses ci-dessous).
System.out.println("YOUR STRING" + YOUR_DOUBLE_VARIABLE);
Réponses:
Si l'idée est d'imprimer des entiers stockés en double comme s'ils étaient des entiers, et sinon d'imprimer les doubles avec la précision minimale nécessaire:
Produit:
Et ne repose pas sur la manipulation de chaînes.
la source
double
supérieure à laint
valeur maximale . Même aveclong
cela, il échouerait toujours pour un grand nombre. De plus, il retournera une chaîne sous une forme exponentielle, par exemple "1.0E10", pour les grandes valeurs, ce qui n'est probablement pas ce que le demandeur veut. Utilisez%f
au lieu de%s
dans la deuxième chaîne de format pour résoudre ce problème.%f
. La réponse est spécifique à la situation décrite et au résultat souhaité. L'OP a suggéré que leur valeur maximale était un entier non signé 32 bits, ce que j'ai comprisint
comme acceptable (non signé qui n'existait pas réellement en Java, et aucun exemple n'était problématique), mais le passageint
àlong
est un correctif trivial si la situation est différente.String.format("%s",d)
??? Parlez des frais généraux inutiles. UtilisezDouble.toString(d)
. Idem pour l'autre:Long.toString((long)d)
.%s
cela ne fonctionne pas avec les paramètres régionaux. En allemand, nous utilisons un "," au lieu d'un "." en nombres décimaux. Alors queString.format(Locale.GERMAN, "%f", 1.5)
renvoie "1 500 000",String.format(Locale.GERMAN, "%s", 1.5)
renvoie "1,5" - avec un ".", Ce qui est faux en langue allemande. Existe-t-il également une version dépendante des paramètres régionaux de «% s»?Comme indiqué dans les commentaires, ce n'est pas la bonne réponse à la question initiale.
Cela dit, c'est un moyen très utile de formater les nombres sans zéros de fin inutiles.
la source
la source
En bref:
Si vous souhaitez vous débarrasser des zéros de fin et des problèmes de paramètres régionaux, vous devez utiliser:
Explication:
Pourquoi les autres réponses ne me convenaient pas:
Double.toString()
ouSystem.out.println
ouFloatingDecimal.toJavaFormatString
utilise des notations scientifiques si le double est inférieur à 10 ^ -3 ou supérieur ou égal à 10 ^ 7en utilisant
%f
, la précision décimale par défaut est 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 :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 doubleen utilisant DecimalFormat, vous êtes dépendant local. Dans les paramètres régionaux français, le séparateur décimal est une virgule, pas un point:
L'utilisation des paramètres régionaux ANGLAIS garantit que vous obtenez un point pour le séparateur décimal, où que votre programme s'exécute
Pourquoi utiliser 340 alors
setMaximumFractionDigits
?Deux raisons :
setMaximumFractionDigits
accepte un entier mais son implémentation a un nombre maximum autorisé de chiffresDecimalFormat.DOUBLE_FRACTION_DIGITS
qui est égal à 340Double.MIN_VALUE = 4.9E-324
donc avec 340 chiffres vous êtes sûr de ne pas arrondir votre précision double et lâchela source
0
au lieu de#.
DecimalFormat.DOUBLE_FRACTION_DIGITS
mais vous utilisez la valeur 340, pour laquelle vous fournissez ensuite un commentaire pour montrer qu'elle est égaleDecimalFormat.DOUBLE_FRACTION_DIGITS
. Pourquoi ne pas simplement utiliser la constante ???Pourquoi pas:
Cela devrait fonctionner avec les valeurs extrêmes prises en charge par Double. Rendements:
la source
"%s"
appelle essentiellementd.toString()
mais cela ne fonctionne pas avecint
ou sid==null
!Sur ma machine, la fonction suivante est environ 7 fois plus rapide que la fonction fournie par la réponse de JasonD , car elle évite
String.format
:la source
Mes 2 cents:
la source
return String.format(Locale.US, (n % 1 == 0 ? "%.0f" : "%.1f"), n);
.Naw, tant pis.
La perte de performances due à la manipulation de chaînes est nulle.
Et voici le code pour couper la fin après
%f
la source
Utilisez un
DecimalFormat
etsetMinimumFractionDigits(0)
la source
setMaximumFractionDigits(2)
etsetGroupingUsed(false)
(OP ne le mentionne pas mais à partir de l'exemple il semble que son requis). De plus, un petit cas de test ne fait pas de mal depuis son trivial dans ce cas. Pourtant, puisque je pense que c'est la solution la plus simple, un vote positif est un vote positif :)la source
Veuillez noter que cela
String.format(format, args...)
dépend des paramètres régionaux car il formate en utilisant les paramètres régionaux par défaut de l'utilisateur, c'est-à-dire, probablement avec des virgules et même des espaces à l'intérieur comme 123 456 789 ou 123 456,789 , ce qui peut ne pas être exactement ce que vous attendez.Vous préférerez peut-être utiliser
String.format((Locale)null, format, args...)
.Par exemple,
impressions
et c'est ce qui va
String.format(format, args...)
fera dans différents pays.EDIT Ok, puisqu'il y a eu une discussion sur les formalités:
la source
J'ai fait un
DoubleFormatter
pour convertir efficacement un grand nombre de valeurs doubles en une chaîne agréable / présentable:Voici le code:
Remarque: j'ai utilisé 2 fonctions de la bibliothèque GUAVA. Si vous n'utilisez pas GUAVA, codez-le vous-même:
la source
Celui-ci fera bien le travail, je sais que le sujet est ancien, mais je luttais avec le même problème jusqu'à ce que j'y arrive. J'espère que quelqu'un le trouvera utile.
la source
la source
la source
Réponse tardive mais ...
Vous avez dit que vous choisissez de stocker vos numéros avec le double type . Je pense que cela pourrait être la racine du problème car cela vous oblige à stocker des entiers en doubles (et donc à perdre les informations initiales sur la nature de la valeur). Qu'en est-il du stockage de vos numéros dans les instances du numéro classe (superclasse de Double et Integer) et comptez sur le polymorphisme pour déterminer le format correct de chaque nombre?
Je sais qu'il n'est peut-être pas acceptable de refactoriser une partie entière de votre code à cause de cela, mais cela pourrait produire la sortie souhaitée sans code / casting / analyse supplémentaire.
Exemple:
Produira la sortie suivante:
la source
Voici ce que j'ai trouvé:
Une doublure simple, ne se jette que si vous en avez vraiment besoin
la source
Format de prix avec regroupement, arrondi, pas de zéros inutiles (en double).
Règles:
2.0000 = 2; 1.0100000 = 1.01
)2.010 = 2.01; 0.20 = 0.2
)1.994 = 1.99; 1.995 = 2; 1.006 = 1.01; 0.0006 -> 0
)0
(null/-0 = 0
)$
(= $56/-$56
)101101.02 = $101,101.02
)Plus d'exemples:
Écrit dans Kotlin comme extension amusante de Double (cause utilisée dans Android), mais peut être converti facilement en Java, car des classes java ont été utilisées.
Comment utiliser:
À propos de DecimalFormat : https://docs.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html
la source
Je devais utiliser cette cause
d == (long)d
me donnait une violation dans le rapport du sonarla source
c'est le résultat de quelques tests:
la source
Voici deux façons d'y parvenir. Tout d'abord, la manière la plus courte (et probablement la meilleure):
Et voici la façon la plus longue et probablement la pire:
la source
Pour Kotlin, vous pouvez utiliser une extension comme:
la source
Voici une autre réponse qui a une option pour ajouter la décimale UNIQUEMENT SI la décimale n'était pas nulle.
la source
Voici une réponse qui fonctionne réellement (combinaison de différentes réponses ici)
la source
Je sais que c'est un fil très ancien .. Mais je pense que la meilleure façon de le faire est la suivante:
Production:
Le seul problème est le dernier où .0 n'est pas supprimé. Mais si vous êtes en mesure de vivre avec cela, cela fonctionne mieux. % .2f l'arrondira aux 2 derniers chiffres décimaux. DecimalFormat aussi. Si vous avez besoin de toutes les décimales mais pas des zéros de fin, cela fonctionne mieux.
la source
System.out.println(new java.text.DecimalFormat("#.##").format(1.0005));
imprimera1
Cela fera que la chaîne laissera tomber les 0-s de queue.
la source