118 votes

Meilleure façon d'afficher les décimales sans les zéros de fin

Existe-t-il un formateur d'affichage qui permette d'afficher les décimales sous la forme de ces chaînes de caractères en c# sans faire d'arrondi ?

// decimal -> string

20 -> 20
20.00 -> 20
20.5 -> 20.5
20.5000 -> 20.5
20.125 -> 20.125
20.12500 -> 20.125
0.000 -> 0

{0.#} sera arrondi, et l'utilisation d'une fonction de type Trim ne fonctionnera pas avec une colonne numérique liée dans une grille.

161voto

Toby Points 4112

Avez-vous un nombre maximum de décimales à afficher ? (Vos exemples ont un maximum de 5).

Si c'est le cas, je pense que la mise en forme avec "0.#####" donnera les résultats escomptés.

    static void Main(string[] args)
    {
        var dList = new decimal[] { 20, 20.00m, 20.5m, 20.5000m, 20.125m, 20.12500m, 0.000m };

        foreach (var d in dList)
            Console.WriteLine(d.ToString("0.#####"));
    }

5 votes

Et vous pouvez toujours ajouter un nombre exorbitant* de symboles # au format. *pas scientifique

3 votes

+1 - d'ailleurs, vous n'avez pas besoin du # qui précède. "0.#####" fonctionne de la même manière. Quoi qu'il en soit, l'arrondi se fait à partir de zéro (pour information).

0 votes

Merci, je n'avais plus qu'à l'utiliser !

42voto

Schmalls Points 430

Je viens d'apprendre à utiliser correctement le G spécificateur de format. Voir le Documentation MSDN . Une note un peu plus bas indique que les zéros de fin seront conservés pour les types décimaux lorsqu'aucune précision n'est spécifiée. Je ne sais pas pourquoi ils font cela, mais le fait de spécifier le nombre maximum de chiffres pour notre précision devrait résoudre ce problème. Donc, pour le formatage des décimales, G29 est la meilleure solution.

decimal test = 20.5000m;
test.ToString("G"); // outputs 20.5000 like the documentation says it should
test.ToString("G29"); // outputs 20.5 which is exactly what we want

25 votes

Ainsi, 0,00001 s'affichera sous la forme de 1E-05.

18voto

Erwin Mayer Points 3427

Ce format de chaîne devrait vous réjouir : "0.#############################". N'oubliez pas que les décimales peuvent avoir au maximum 29 chiffres significatifs.

Exemples :

? (1000000.00000000000050000000000m).ToString("0.#############################")
-> 1000000.0000000000005

? (1000000.00000000000050000000001m).ToString("0.#############################")
-> 1000000.0000000000005

? (1000000.0000000000005000000001m).ToString("0.#############################")
-> 1000000.0000000000005000000001

? (9223372036854775807.0000000001m).ToString("0.#############################")
-> 9223372036854775807

? (9223372036854775807.000000001m).ToString("0.#############################")
-> 9223372036854775807.000000001

4 votes

C'est la réponse la plus générale au problème. Je ne sais pas pourquoi ce n'est pas le format "G" par défaut pour les décimales. Les zéros de fin n'ajoutent aucune information. La documentation de Microsoft contient une mise en garde étrange pour les décimales : docs.microsoft.com/en-us/dotnet/standard/base-types/ Toutefois, si le nombre est un nombre décimal et que le spécificateur de précision est omis, la notation en virgule fixe est toujours utilisée et les zéros de fin sont préservés.

11voto

dyslexicanaboko Points 2116

Il s'agit d'une autre variante de ce que j'ai vu plus haut. Dans mon cas, je dois conserver tous les chiffres significatifs à droite de la virgule, c'est-à-dire supprimer tous les zéros après le chiffre le plus significatif. J'ai juste pensé qu'il serait bon de le partager. Je ne peux pas me porter garant de l'efficacité de cette méthode, mais lorsque l'on essaie d'atteindre l'esthétique, on est déjà condamné à l'inefficacité.

public static string ToTrimmedString(this decimal target)
{
    string strValue = target.ToString(); //Get the stock string

    //If there is a decimal point present
    if (strValue.Contains("."))
    {
        //Remove all trailing zeros
        strValue = strValue.TrimEnd('0');

        //If all we are left with is a decimal point
        if (strValue.EndsWith(".")) //then remove it
            strValue = strValue.TrimEnd('.');
    }

    return strValue;
}

C'est tout, je voulais juste donner mon avis.

3 votes

C'est facilement la meilleure solution, elle n'explose pas pour "0.0" non plus. J'ai ajouté un drapeau par défaut pour que les entiers s'affichent optionnellement comme "1.0", et cela a permis à toutes mes décimales de s'aligner. Je ne comprends pas pourquoi ce n'est pas la meilleure solution, +lots.

2 votes

C'est particulièrement utile si quelqu'un vous a déjà passé une chaîne. Il suffit de la remplacer par ToTrimmedString(this string strValue) et de supprimer la première ligne.

0 votes

C'est un bon point. Je pense que lorsque j'ai écrit cela, j'avais affaire à des valeurs qui étaient déjà des décimales ou quelque chose comme ça, alors j'ai voulu englober le tout. Vous pourriez plutôt avoir le corps de cette méthode à l'intérieur d'une autre méthode surchargée qui accepte une chaîne de caractères à la place.

2voto

jgauffin Points 51913

Méthode d'extension :

public static class Extensions
{
    public static string TrimDouble(this string temp)
    {
        var value = temp.IndexOf('.') == -1 ? temp : temp.TrimEnd('.', '0');
        return value == string.Empty ? "0" : value;
    }
}

Exemple de code :

double[] dvalues = {20, 20.00, 20.5, 20.5000, 20.125, 20.125000, 0.000};
foreach (var value in dvalues)
    Console.WriteLine(string.Format("{0} --> {1}", value, value.ToString().TrimDouble()));

Console.WriteLine("==================");

string[] svalues = {"20", "20.00", "20.5", "20.5000", "20.125", "20.125000", "0.000"};
foreach (var value in svalues)
    Console.WriteLine(string.Format("{0} --> {1}", value, value.TrimDouble()));

Sortie :

20 --> 20
20 --> 20
20,5 --> 20,5
20,5 --> 20,5
20,125 --> 20,125
20,125 --> 20,125
0 --> 0
==================
20 --> 20
20.00 --> 2
20.5 --> 20.5
20.5000 --> 20.5
20.125 --> 20.125
20.125000 --> 20.125
0.000 --> 0

1 votes

"20.00 --> 2" Je pense que ce n'est pas un bon comportement. Pour y remédier, il faut appeler TrimEnd deux fois : TrimEnd('0') ; TrimEnd(',') ;

4 votes

N'UTILISEZ PAS le code écrit ci-dessus. @VadymK a raison de dire que son comportement est défectueux. Il coupera les zéros de fin qui sont AVANT le point s'il n'y a pas de point.

2 votes

Les réponses sur stackoverflow ne sont pas à copier-coller. Elles sont utilisées comme source de l'apprentissage . Ce code sampel vous apprend à utiliser IndexOf pour trouver des caractères dans une chaîne de caractères. Il est assez facile d'adapter l'exemple pour résoudre le problème sans décimales.

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