web-dev-qa-db-fra.com

Supprimer les zéros de fin

J'ai des champs retournés par une collection comme

2.4200
2.0044
2.0000

Je veux des résultats comme

2.42
2.0044
2

J'ai essayé avec String.Format, mais il retourne 2.0000 et le définit sur N0 arrondit également les autres valeurs.

142
Zo Has

N'est-ce pas aussi simple que cela, si l'entrée IS est une chaîne? Vous pouvez utiliser l'un de ceux-ci:

string.Format("{0:G29}", decimal.Parse("2.0044"))

decimal.Parse("2.0044").ToString("G29")

2.0m.ToString("G29")

Cela devrait fonctionner pour toutes les entrées.

Update Découvrez les Formats numériques standard J'ai dû définir explicitement le spécificateur de précision sur 29, car la documentation indique clairement:

Toutefois, si le nombre est un nombre décimal et que le spécificateur de précision est omis, la notation en point fixe est toujours utilisée et les zéros de fin sont préservés.

UpdateKonrada souligné dans les commentaires:

Méfiez-vous des valeurs telles que 0.000001. Le format G29 les présentera le plus rapidement 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.

144
Dog Ears

J'ai rencontré le même problème, mais dans un cas où je n'ai pas le contrôle de la sortie de chaîne, qui était 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 ), astuce soignée (ici comme méthode d'extension):

public static decimal Normalize(this decimal value)
{
    return value/1.000000000000000000000000000000000m;
}

La partie exposant de la décimale est réduite à ce qui est nécessaire. L'appel de ToString () sur le décimal de sortie écrira le nombre sans point final 0. E.g.

1.200m.Normalize().ToString();
172
Thomas Materna

À mon avis, il est plus sûr d'utiliser Chaînes de format numérique personnalisées .

decimal d = 0.00000000000010000000000m;
string custom = d.ToString("0.#########################");
// gives: 0,0000000000001
string general = d.ToString("G29");
// gives: 1E-13
76
Michał Powaga

J'utilise ce code pour éviter la notation scientifique "G29":

public static string DecimalToString(decimal dec)
{
    string strdec = dec.ToString(CultureInfo.InvariantCulture);
    return strdec.Contains(".") ? strdec.TrimEnd('0').TrimEnd('.') : strdec;
}
26
x7iBiT

Utilisez le symbole dièse (#) pour afficher uniquement les 0 finaux si nécessaire. Voir les tests ci-dessous.

decimal num1 = 13.1534545765;
decimal num2 = 49.100145;
decimal num3 = 30.000235;

num1.ToString("0.##");       //13.15%
num2.ToString("0.##");       //49.1%
num3.ToString("0.##");       //30%
11
Fizzix

J'ai trouvé une solution élégante de http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/

Fondamentalement 

virgule décimale = 2,4200M;

v.ToString ("#. ######"); // retournera 2.42. Le nombre de # correspond au nombre de chiffres décimaux que vous prenez en charge.

9
DHornpout

Cela fonctionnera:

decimal source = 2.4200m;
string output = ((double)source).ToString();

Ou si votre valeur initiale est string:

string source = "2.4200";
string output = double.Parse(source).ToString();

Faites attention à ce commentaire .

3
Shimmy

Une approche de très bas niveau, mais je pense que ce serait la manière la plus performante de n'utiliser que des calculs entiers rapides (et pas de méthodes d'analyse syntaxique de chaînes lentes et sensibles à la culture):

public static decimal Normalize(this decimal d)
{
    int[] bits = decimal.GetBits(d);

    int sign = bits[3] & (1 << 31);
    int exp = (bits[3] >> 16) & 0x1f;

    uint a = (uint)bits[2]; // Top bits
    uint b = (uint)bits[1]; // Middle bits
    uint c = (uint)bits[0]; // Bottom bits

    while (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;
    return new decimal(bits);
}

private static uint DivideBy10(uint highBits, uint lowBits, out uint remainder)
{
    ulong total = highBits;
    total <<= 32;
    total = total | (ulong)lowBits;

    remainder = (uint)(total % 10L);
    return (uint)(total / 10L);
}
1
Bigjim

Cela dépend de ce que votre nombre représente et de la manière dont vous voulez gérer les valeurs: s'agit-il d'une devise, avez-vous besoin d'arrondir ou de troncer, avez-vous besoin de cet arrondi uniquement pour l'affichage?

Si pour l'affichage envisager de formater 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'arrondir, utilisez la 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 d'utiliser la conversion au lieu de la conversion: Double value = (decimal) myRecord ["columnName"];

1
florin

Si vous souhaitez conserver un nombre décimal, essayez l'exemple suivant:

number = Math.Floor(number * 100000000) / 100000000;
0
phuongnd

La réponse très simple consiste à utiliser TrimEnd (). Voici le résultat,

double value = 1.00;
string output = value.ToString().TrimEnd('0');

La sortie est 1 Si ma valeur est 1.01 alors ma sortie sera 1.01

0
Raj De Inno

C'est simple.

decimal decNumber = Convert.ToDecimal(value);
        return decNumber.ToString("0.####");

Testé.

À votre santé :)

0
Rakesh