web-dev-qa-db-fra.com

Comment arrondir une valeur décimale à 2 décimales (pour la sortie sur une page)

Lors de l'affichage de la valeur d'une décimale actuellement avec .ToString(), il est précis de 15 décimales, et comme je l'utilise pour représenter des dollars et des cents, je ne souhaite que la sortie soit à 2 décimales.

Est-ce que j'utilise une variante de .ToString() pour cela?

597
wows
decimalVar.ToString ("#.##"); // returns "" when decimalVar == 0

ou

decimalVar.ToString ("0.##"); // returns "0"  when decimalVar == 0
839
albertein

Je sais que c’est une vieille question, mais j’ai été surpris de constater que personne ne semblait répondre à cette question;

  1. N'a pas utilisé l'arrondissement des banquiers
  2. N'a pas gardé la valeur sous forme décimale.

C'est ce que j'utiliserais:

decimal.Round(yourValue, 2, MidpointRounding.AwayFromZero);

http://msdn.Microsoft.com/en-us/library/9s0xa85y.aspx

554
Mike M.
decimalVar.ToString("F");

Cette volonté:

  • Arrondir à 2 décimales, par exemple. 23,456 => 23,46
  • Assurez-vous qu'il y a toujours 2 décimales, par exemple. 23 => 23,00, 12,5 => 12,50

Idéal pour la monnaie et l'affichage des montants monétaires.

Pour la documentation sur ToString ("F"): http://msdn.Microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx#FFormatString (avec le remerciement de Jon Schneider)

319
Sofox

Si vous avez juste besoin de cela pour l'affichage, utilisez string.Format

String.Format("{0:0.00}", 123.4567m);      // "123.46"

http://www.csharp-examples.net/string-format-double/

Le "m" est un suffixe décimal. À propos du suffixe décimal:

http://msdn.Microsoft.com/en-us/library/364x0z75.aspx

102
Jorge Ferreira

Étant donné décimal d = 12.345; les expressions d.ToString ("C") ou String.Format ("{0: C}", d) donne 12,35 $ - Notez que les paramètres de devise de la culture actuelle, y compris le symbole, sont utilisés.

Notez que "C" utilise le nombre de chiffres de la culture actuelle. Vous pouvez toujours remplacer la valeur par défaut pour forcer la précision nécessaire avec C{Precision specifier} comme String.Format("{0:C2}", 5.123d).

55
Hafthor

Si vous souhaitez le mettre en forme avec des virgules et un point décimal (mais pas de symbole monétaire), tel que 3 356 789,12 ...

decimalVar.ToString("n2");
45
Joel Mueller

Il existe déjà deux réponses très cotées qui font référence à Decimal.Round (...), mais je pense qu'un peu plus d'explication est nécessaire - car il existe une propriété importante et inattendue de Decimal qui n'est pas évidente.

Une virgule "sait" combien de décimales elle a été créée en fonction de son origine.

Par exemple, les éléments suivants peuvent être inattendus:

Decimal.Parse("25").ToString()          =>   "25"
Decimal.Parse("25.").ToString()         =>   "25"
Decimal.Parse("25.0").ToString()        =>   "25.0"
Decimal.Parse("25.0000").ToString()     =>   "25.0000"

25m.ToString()                          =>   "25"
25.000m.ToString()                      =>   "25.000"

Effectuer les mêmes opérations avec Double ne donnera aucune décimale ("25") pour chacun des éléments ci-dessus.

Lorsque vous voulez une décimale à 2 décimales, il y a environ 95% de chances que ce soit parce que c'est la devise, auquel cas c'est probablement bien pour 95% du temps:

Decimal.Parse("25.0").ToString("c")     =>   "$25.00"

Ou, en XAML, vous utilisez simplement {Binding Price, StringFormat=c}

Un cas que j'ai rencontré où j'avais besoin d'une décimale comme décimale était lors de l'envoi de XML au service Web d'Amazon. Le service se plaignait car une valeur décimale (à l'origine de SQL Server) était envoyée sous le nom 25.1200 et rejetée (25.12 était le format attendu).

Tout ce que je devais faire était Decimal.Round(...) avec 2 décimales pour résoudre le problème.

 // This is an XML message - with generated code by XSD.exe
 StandardPrice = new OverrideCurrencyAmount()
 {
       TypedValue = Decimal.Round(product.StandardPrice, 2),
       currency = "USD"
 }

TypedValue est de type Decimal et je ne pouvais donc pas simplement faire ToString("N2"), je devais l'arrondir et le conserver en tant que decimal.

29
Simon_Weaver

Voici un petit programme Linqpad pour montrer différents formats:

void Main()
{
    FormatDecimal(2345.94742M);
    FormatDecimal(43M);
    FormatDecimal(0M);
    FormatDecimal(0.007M);
}

public void FormatDecimal(decimal val)
{
    Console.WriteLine("ToString: {0}", val);
    Console.WriteLine("c: {0:c}", val);
    Console.WriteLine("0.00: {0:0.00}", val);
    Console.WriteLine("0.##: {0:0.##}", val);
    Console.WriteLine("===================");
}

Voici les résultats:

ToString: 2345.94742
c: $2,345.95
0.00: 2345.95
0.##: 2345.95
===================
ToString: 43
c: $43.00
0.00: 43.00
0.##: 43
===================
ToString: 0
c: $0.00
0.00: 0.00
0.##: 0
===================
ToString: 0.007
c: $0.01
0.00: 0.01
0.##: 0.01
===================
21
What Would Be Cool
15
John Smith

Très rarement voudriez-vous une chaîne vide si la valeur est 0.

decimal test = 5.00;
test.ToString("0.00");  //"5.00"
decimal? test2 = 5.05;
test2.ToString("0.00");  //"5.05"
decimal? test3 = 0;
test3.ToString("0.00");  //"0.00"

La réponse la mieux notée est incorrecte et a perdu 10 minutes de temps (de la plupart des) personnes.

10
goamn

Aucun de ceux-ci n'a fait exactement ce dont j'avais besoin, pour forcer 2 d.p. et arrondi par 0.005 -> 0.01

Forcer 2 p.p. nécessite d’augmenter la précision de 2 d.p. pour s'assurer que nous avons au moins 2 dp.

puis nous arrondissons pour nous assurer que nous n’avons pas plus de 2d.p.

Math.Round(exactResult * 1.00m, 2, MidpointRounding.AwayFromZero)

6.665m.ToString() -> "6.67"

6.6m.ToString() -> "6.60"
9
Kaido

La réponse la mieux notée décrit une méthode pour formater la représentation sous forme de chaîne de la valeur décimale, et cela fonctionne.

Toutefois, si vous souhaitez réellement modifier la précision enregistrée en valeur réelle, vous devez écrire quelque chose comme ce qui suit:

public static class PrecisionHelper
{
    public static decimal TwoDecimalPlaces(this decimal value)
    {
        // These first lines eliminate all digits past two places.
        var timesHundred = (int) (value * 100);
        var removeZeroes = timesHundred / 100m;

        // In this implementation, I don't want to alter the underlying
        // value.  As such, if it needs greater precision to stay unaltered,
        // I return it.
        if (removeZeroes != value)
            return value;

        // Addition and subtraction can reliably change precision.  
        // For two decimal values A and B, (A + B) will have at least as 
        // many digits past the decimal point as A or B.
        return removeZeroes + 0.01m - 0.01m;
    }
}

Un exemple de test unitaire:

[Test]
public void PrecisionExampleUnitTest()
{
    decimal a = 500m;
    decimal b = 99.99m;
    decimal c = 123.4m;
    decimal d = 10101.1000000m;
    decimal e = 908.7650m

    Assert.That(a.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("500.00"));

    Assert.That(b.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("99.99"));

    Assert.That(c.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("123.40"));

    Assert.That(d.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("10101.10"));

    // In this particular implementation, values that can't be expressed in
    // two decimal places are unaltered, so this remains as-is.
    Assert.That(e.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("908.7650"));
}
8
Alex

Vous pouvez utiliser system.globalization pour formater un nombre dans n'importe quel format requis.

Par exemple:

system.globalization.cultureinfo ci = new system.globalization.cultureinfo("en-ca");

Si vous avez un decimal d = 1.2300000 et que vous devez le réduire à 2 décimales, il peut être imprimé comme ceci d.Tostring("F2",ci); où F2 est une chaîne de caractères formatant à 2 décimales et ci est le paramètre régional ou cultureinfo.

pour plus d'informations, consultez ce lien
http://msdn.Microsoft.com/en-us/library/dwhawy9k.aspx

7
Smitha Poluri

La réponse de Mike M. était parfait pour moi sur .NET, mais .NET Core n'a pas de méthode decimal.Round au moment de la rédaction.

Dans .NET Core, je devais utiliser:

decimal roundedValue = Math.Round(rawNumber, 2, MidpointRounding.AwayFromZero);

Une méthode de hacky, y compris la conversion en chaîne, est la suivante:

public string FormatTo2Dp(decimal myNumber)
{
    // Use schoolboy rounding, not bankers.
    myNumber = Math.Round(myNumber, 2, MidpointRounding.AwayFromZero);

    return string.Format("{0:0.00}", myNumber);
}
6
HockeyJ

https://msdn.Microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx

Ce lien explique en détail comment vous pouvez gérer votre problème et ce que vous pouvez faire si vous voulez en savoir plus. Pour des raisons de simplicité, ce que vous voulez faire est

double whateverYouWantToChange = whateverYouWantToChange.ToString("F2");

si vous voulez ceci pour une devise, vous pouvez le simplifier en tapant "C2" au lieu de "F2"

4
Jeff Jose
Double Amount = 0;
string amount;
amount=string.Format("{0:F2}", Decimal.Parse(Amount.ToString()));
0
JIYAUL MUSTAPHA