initialement le type d'enregistrement est une chaîne ??
Singleton
2
Voir ma réponse: String.Format()avec «G» devrait obtenir ce que vous voulez .. j'ai mis à jour ma réponse avec un lien vers les formats numériques standard. Très utile.
Dog Ears
3
Un décimal peut être converti en double, et la valeur ToStringpar défaut pour double émet les zéros de fin. lire ceci
Shimmy Weitzhandler
2
Et cela coûtera probablement moins de performances (pour un très grand nombre d'enregistrements) que de passer le "G" comme format de chaîne à la ToStringfonction.
Shimmy Weitzhandler du
4
Vous ne devriez pas convertir une décimale en double, cela perdra de son importance et pourrait introduire une puissance de deux inexactitudes d'arrondi.
kristianp
Réponses:
167
N'est-ce pas aussi simple que cela, si l'entrée EST une chaîne? Vous pouvez utiliser l'un de ceux-ci:
Mise à jour Vérifiez les formats numériques standard que j'ai dû définir explicitement le spécificateur de précision sur 29, comme l'indique clairement la documentation:
Cependant, si le nombre est un décimal et que le spécificateur de précision est omis, la notation à virgule fixe est toujours utilisée et les zéros de fin sont conservés
Méfiez-vous des valeurs comme 0,000001. Le format G29 les présentera de la manière la plus courte possible afin de passer à la notation exponentielle. string.Format("{0:G29}", decimal.Parse("0.00000001",System.Globalization.CultureInfo.GetCultureInfo("en-US")))donnera "1E-08" comme résultat.
De toutes les réponses, c'est la vôtre qui a impliqué le moins d'étapes. Merci Dog Ears.
Zo a
4
var d = 2,0 m; d.ToString ("G");
Dave Hillier
3
@Dave Hillier - Je vois, j'ai corrigé ma réponse. À votre santé. [ajout d'un "spécificateur de précision" explicite]
Dog Ears
16
Méfiez-vous des valeurs comme 0,000001. Le format G29 les présentera de la manière la plus courte possible afin de passer à la notation exponentielle. string.Format ("{0: G29}", decimal.Parse ("0.00000001", System.Globalization.CultureInfo.GetCultureInfo ("en-US"))) donnera "1E-08" comme résultat
Konrad
15
@Konrad - y a-t-il un moyen d'éviter la notation scientifique pour les nombres qui ont 5 ou 6 décimales?
Jill
202
J'ai rencontré le même problème mais dans un cas où je n'ai pas le contrôle de la sortie en chaîne, qui a été prise en charge par une bibliothèque. Après avoir examiné les détails de l'implémentation du type Decimal (voir http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx ), j'ai trouvé une astuce intéressante (ici en extension méthode):
La partie exposant de la décimale est réduite à ce qui est nécessaire. L'appel de ToString () sur la décimale de sortie écrira le nombre sans aucun 0 à la fin. Par exemple
Cette réponse est propre parce que contrairement à pratiquement toutes les autres réponses à cette question (et même à tout le sujet), fonctionne réellement et fait ce que le PO demande.
Coxy
2
le nombre de 0 est-il ici une quantité exacte ou simplement pour couvrir la plupart des valeurs attendues?
Simon_Weaver
3
MSDN déclare "Le facteur d'échelle est implicitement le nombre 10, élevé à un exposant allant de 0 à 28", ce que je comprends comme le nombre décimal aura au plus 28 chiffres au-delà du point décimal. N'importe quel nombre de zéros> = 28 devrait fonctionner.
Thomas Materna
2
C'est la meilleure réponse! Le nombre dans la réponse a 34 chiffres, le 1suivi de 33 0-s, mais cela crée exactement la même decimalinstance qu'un nombre avec 29 chiffres, un 1et 28 0-s. Tout comme @ThomasMaterna l'a dit dans son commentaire. Non System.Decimalpeut avoir plus de 29 chiffres (les nombres avec les premiers chiffres supérieurs à 79228...ne peuvent avoir que 28 chiffres au total). Si vous voulez plus de zéros de fin, multipliez par 1.000...mau lieu de diviser. En outre, Math.Roundpeut couper certains zéros, par exemple Math.Round(27.40000m, 2)donne 27.40m, donc un seul zéro à gauche.
Jeppe Stig Nielsen
2
Excellent truc mais ne fonctionne PAS sur Mono et n'est pas garanti pour fonctionner sur les versions fonctionnelles de .NET
C'est une merveilleuse réponse. C'est très simple et vous pouvez voir exactement ce qui se passe au lieu d'utiliser un formateur de chaîne magique.
Timothy Gonzalez
9
Bien, mais cela ne fonctionnera pas pour les cultures qui utilisent la virgule comme séparateur décimal. Vous auriez besoin d'utiliserCulture.NumberFormat.NumberDecimalSeparator
blearyeye
1
Meilleure approche. Tout le reste est inutilement compliqué. N'oubliez pas de toujours vérifier si votre nombre contient un point décimal.
RRM
1
Pour être une extension, il manque le "this" avant le paramètre: chaîne statique publique DecimalToString (cette décimale décimale)
João Antunes
Merci beaucoup pour les commentaires. J'ai mis à jour la réponse avec une nouvelle version avec les astuces.
x7BiT le
19
Utilisez le #symbole dièse ( ) pour n'afficher que les 0 à la fin lorsque cela est nécessaire. Voir les tests ci-dessous.
Pas une réponse. Vous ne supprimez pas les zéros de fin, vous supprimez la précision. Votre méthode proposée num1.ToString("0.##")doit renvoyer 13.1534545765(aucun changement) car il n'y a pas de zéros à la fin.
Jan 'splite' K.
Et c'est exactement pourquoi j'affiche les réponses à mes trois entrées proposées afin que les utilisateurs puissent voir comment ma solution fonctionne.
Fizzix
Il ne répond pas à la question même si vous listez les entrées proposées.
Dave Friedel
2
Id upvote ceci 10 fois si je pouvais. Exactement ce dont j'avais besoin!
SubqueryCrunch
1
Réponse parfaite à la question. MEILLEURE réponse à mon avis. Le commentaire qu'il supprime la précision est correct, mais ce n'était pas la question. Le plus important - c'est ce dont j'ai besoin. Mes utilisateurs entreront généralement des nombres entiers, peut-être quelque chose comme 2,5, mais je dois prendre en charge 3 chiffres au-delà du point décimal. Je veux donc leur donner ce qu'ils sont entrés, pas avec un tas de zéros qu'ils n'ont pas entrés. par exemple, Console.Write ($ "num3 = {num3: 0. ##}"); => num3 = 30
Notez que si vest 0mle résultat de votre code est une chaîne vide plutôt que "0".
Sam
2
Oui. Il doit être "0. ########".
PRMan
2
Une approche de très bas niveau, mais je pense que ce serait le moyen le plus performant en utilisant uniquement des calculs d'entiers rapides (et pas de méthodes d'analyse lente des chaînes et sensibles à la culture):
publicstaticdecimalNormalize(thisdecimal d){int[] bits =decimal.GetBits(d);int sign = bits[3]&(1<<31);int exp =(bits[3]>>16)&0x1f;uint a =(uint)bits[2];// Top bitsuint b =(uint)bits[1];// Middle bitsuint c =(uint)bits[0];// Bottom bitswhile(exp >0&&((a %5)*6+(b %5)*6+ c)%10==0){uint r;
a =DivideBy10((uint)0, a,out r);
b =DivideBy10(r, b,out r);
c =DivideBy10(r, c,out r);
exp--;}
bits[0]=(int)c;
bits[1]=(int)b;
bits[2]=(int)a;
bits[3]=(exp <<16)| sign;returnnewdecimal(bits);}privatestaticuintDivideBy10(uint highBits,uint lowBits,outuint remainder){ulong total = highBits;
total <<=32;
total = total |(ulong)lowBits;
remainder =(uint)(total %10L);return(uint)(total /10L);}
@Damien, oui, et notez que pour ces raisons (vous ne ressentirez rien à moins de faire un milliard d'enregistrements), d'une part parce que le double est plus rapide, d'autre part, parce que passer un format de chaîne à la fonction ToString coûte plus de performances qu'autrement passer des paramètres. encore une fois, vous ne ressentirez rien à moins de travailler sur des milliards de disques.
Shimmy Weitzhandler
1
Vous n'avez pas à spécifier G, car double.ToStringpar défaut, les zéros de fin sont supprimés.
Shimmy Weitzhandler
4
Méfiez-vous des valeurs comme 0,000001. Ceux-ci seront présentés dans la notation exponentielle. double.Parse ("0.00000001", System.Globalization.CultureInfo.GetCultureInfo ("en-US")). ToString () donnera "1E-08" comme résultat
Konrad
17
Ne faites JAMAIS ça. Habituellement, la raison pour laquelle vous avez une décimale est que vous représentez un nombre avec précision (pas à peu près comme le fait un double). Certes, cette erreur en virgule flottante est probablement assez petite, mais pourrait entraîner l'affichage de nombres incorrects, néanmoins
Adam Tegen
2
Aïe, convertir un type de données 128 bits (décimal) en un type de données 64 bits (double) pour le formatage, n'est pas une bonne idée!
Cela dépend de ce que représente votre nombre et de la façon dont vous souhaitez gérer les valeurs: est-ce une devise, avez-vous besoin d'arrondi ou de troncature, avez-vous besoin de cet arrondi uniquement pour l'affichage?
Si pour l'affichage, pensez au formatage, les nombres sont x.ToString ("")
Si vous obtenez votre valeur à partir d'une base de données, envisagez la conversion au lieu de la conversion: double value = (decimal) myRecord ["columnName"];
privatestaticdecimalTrim(thisdecimalvalue){var s =value.ToString(CultureInfo.InvariantCulture);return s.Contains(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator)?Decimal.Parse(s.TrimEnd('0'),CultureInfo.InvariantCulture):value;}privatestaticdecimal?Trim(thisdecimal?value){returnvalue.HasValue?(decimal?)value.Value.Trim():null;}privatestaticvoidMain(string[] args){Console.WriteLine("=>{0}",1.0000m.Trim());Console.WriteLine("=>{0}",1.000000023000m.Trim());Console.WriteLine("=>{0}",((decimal?)1.000000023000m).Trim());Console.WriteLine("=>{0}",((decimal?)null).Trim());}
(I) -> Analyser la valeur décimale de n'importe quelle source de chaîne.
(II) -> First: Cast pour doubler cette suppression des zéros de fin. Deuxièmement: Autre conversion en décimal car il n'existe pas de conversion implicite de décimal en double et vice versa)
Vous supposez toutes les valeurs qui tiendraient dans une décimale, tenir dans un double. Cela peut provoquer une OverflowExeception. Vous pouvez également perdre de la précision.
pas une option du tout en comparaison avec d'autres approches dans ce poste. La conversion en chaîne et inversement est toujours une mauvaise option pour manipuler les nombres (au moins à cause des paramètres régionaux)
Vladimir Semashkin
-11
essayez comme ça
string s ="2.4200";
s = s.TrimStart('0').TrimEnd('0','.');
vous pouvez utiliser la subString()méthode pour cela, mais selon la question postée ici, je ne vois aucune exigence comme celle-là =)
Singleton
2
Qu'en est-il des paramètres régionaux qui n'utilisent pas "."
Dave Hillier
10
Cela échoue lamentablement pour les nombres qui sont un multiple pair de 10,0.
Ben Voigt le
1
Ce que @BenVoigt a dit est tout à fait correct, car un exemple "12300.00"sera réduit "123". Un autre effet qui semble indésirable est que certains nombres, tels que, "0.00"sont coupés jusqu'à la chaîne vide ""(bien que ce nombre soit un cas particulier d'être un «multiple entier de 10,0»).
String.Format()
avec «G» devrait obtenir ce que vous voulez .. j'ai mis à jour ma réponse avec un lien vers les formats numériques standard. Très utile.double
, et la valeurToString
par défaut pour double émet les zéros de fin. lire ceciToString
fonction.Réponses:
N'est-ce pas aussi simple que cela, si l'entrée EST une chaîne? Vous pouvez utiliser l'un de ceux-ci:
Cela devrait fonctionner pour toutes les entrées.
Mise à jour Vérifiez les formats numériques standard que j'ai dû définir explicitement le spécificateur de précision sur 29, comme l'indique clairement la documentation:
Update Konrad a souligné dans les commentaires:
la source
J'ai rencontré le même problème mais dans un cas où je n'ai pas le contrôle de la sortie en chaîne, qui a été prise en charge par une bibliothèque. Après avoir examiné les détails de l'implémentation du type Decimal (voir http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx ), j'ai trouvé une astuce intéressante (ici en extension méthode):
La partie exposant de la décimale est réduite à ce qui est nécessaire. L'appel de ToString () sur la décimale de sortie écrira le nombre sans aucun 0 à la fin. Par exemple
la source
1
suivi de 330
-s, mais cela crée exactement la mêmedecimal
instance qu'un nombre avec 29 chiffres, un1
et 280
-s. Tout comme @ThomasMaterna l'a dit dans son commentaire. NonSystem.Decimal
peut avoir plus de 29 chiffres (les nombres avec les premiers chiffres supérieurs à79228...
ne peuvent avoir que 28 chiffres au total). Si vous voulez plus de zéros de fin, multipliez par1.000...m
au lieu de diviser. En outre,Math.Round
peut couper certains zéros, par exempleMath.Round(27.40000m, 2)
donne27.40m
, donc un seul zéro à gauche.À mon avis, il est plus sûr d'utiliser des chaînes de format numérique personnalisées .
la source
J'utilise ce code pour éviter la notation scientifique "G29":
EDIT: en utilisant le système CultureInfo.NumberFormat.NumberDecimalSeparator:
la source
Culture.NumberFormat.NumberDecimalSeparator
Utilisez le
#
symbole dièse ( ) pour n'afficher que les 0 à la fin lorsque cela est nécessaire. Voir les tests ci-dessous.la source
num1.ToString("0.##")
doit renvoyer13.1534545765
(aucun changement) car il n'y a pas de zéros à la fin.J'ai trouvé une solution élégante sur http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/
Fondamentalement
la source
v
est0m
le résultat de votre code est une chaîne vide plutôt que"0"
.Une approche de très bas niveau, mais je pense que ce serait le moyen le plus performant en utilisant uniquement des calculs d'entiers rapides (et pas de méthodes d'analyse lente des chaînes et sensibles à la culture):
la source
a
etb
) dans chaque itération while s'ils sont tous à zéro de toute façon. Cependant, j'ai trouvé cette solution étonnamment simple qui bat également facilement ce que vous et moi avons proposé en termes de performances .Cela fonctionnera:
Ou si votre valeur initiale est
string
:Faites attention à ce commentaire .
la source
double.ToString
par défaut, les zéros de fin sont supprimés.C'est simple.
Testé.
À votre santé :)
la source
Cela dépend de ce que représente votre nombre et de la façon dont vous souhaitez gérer les valeurs: est-ce une devise, avez-vous besoin d'arrondi ou de troncature, avez-vous besoin de cet arrondi uniquement pour l'affichage?
Si pour l'affichage, pensez au formatage, les nombres sont x.ToString ("")
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx et
http://msdn.microsoft.com/en-us/library/0c899ak8.aspx
S'il s'agit simplement d'arrondi, utilisez une surcharge Math.Round qui nécessite une surcharge MidPointRounding
http://msdn.microsoft.com/en-us/library/ms131274.aspx )
Si vous obtenez votre valeur à partir d'une base de données, envisagez la conversion au lieu de la conversion: double value = (decimal) myRecord ["columnName"];
la source
Vous pouvez simplement définir comme:
la source
Si vous souhaitez conserver le nombre décimal, essayez l'exemple suivant:
la source
Essayer de faire une solution plus conviviale de DecimalToString ( https://stackoverflow.com/a/34486763/3852139 ):
Production:
la source
La réponse très simple consiste à utiliser TrimEnd (). Voici le résultat,
La sortie est 1 Si ma valeur est 1,01, ma sortie sera 1,01
la source
value = 100
?Le code suivant peut être utilisé pour ne pas utiliser le type chaîne:
Renvoie 789,5
la source
Tronquer les zéros de fin est très simple, résolvez-les avec une conversion duplex:
(I) -> Analyser la valeur décimale de n'importe quelle source de chaîne.
(II) -> First: Cast pour doubler cette suppression des zéros de fin. Deuxièmement: Autre conversion en décimal car il n'existe pas de conversion implicite de décimal en double et vice versa)
la source
essayez ce code:
la source
essayez comme ça
puis convertissez cela en float
la source
subString()
méthode pour cela, mais selon la question postée ici, je ne vois aucune exigence comme celle-là =)"12300.00"
sera réduit"123"
. Un autre effet qui semble indésirable est que certains nombres, tels que,"0.00"
sont coupés jusqu'à la chaîne vide""
(bien que ce nombre soit un cas particulier d'être un «multiple entier de 10,0»).