web-dev-qa-db-fra.com

Utilisation du format de chaîne pour afficher des décimales jusqu'à 2 positions ou un entier simple

J'ai un champ de prix à afficher qui peut parfois être 100, 100,99 ou 100,9. Ce que je veux, c'est afficher le prix en deux décimales seulement si les décimales sont entrées pour ce prix, par exemple si sa valeur est égale à 100. afficher 100 pas 100.00 et si le prix est 100.2 il devrait afficher 100.20 de même pour 100.22 devrait être identique. J'ai googlé et rencontré quelques exemples, mais ils ne correspondaient pas exactement à ce que je voulais:

// just two decimal places
String.Format("{0:0.00}", 123.4567);      // "123.46"
String.Format("{0:0.00}", 123.4);         // "123.40"
String.Format("{0:0.00}", 123.0);         // "123.00"
251
Mr A

Une manière inélégante serait:

var my = DoFormat(123.0);

Avec DoFormat étant quelque chose comme:

public static string DoFormat( double myNumber )
{
    var s = string.Format("{0:0.00}", myNumber);

    if ( s.EndsWith("00") )
    {
        return ((int)myNumber).ToString();
    }
    else
    {
        return s;
    }
}

Pas élégant mais travailler pour moi dans des situations similaires dans certains projets.

139
Uwe Keim

Désolé de réactiver cette question, mais je n’ai pas trouvé la bonne réponse ici.

Dans le formatage des nombres, vous pouvez utiliser 0 comme emplacement obligatoire et # comme emplacement facultatif.

Donc:

// just two decimal places
String.Format("{0:0.##}", 123.4567);      // "123.46"
String.Format("{0:0.##}", 123.4);         // "123.4"
String.Format("{0:0.##}", 123.0);         // "123"

Vous pouvez également combiner 0 avec #.

String.Format("{0:0.0#}", 123.4567)       // "123.46"
String.Format("{0:0.0#}", 123.4)          // "123.4"
String.Format("{0:0.0#}", 123.0)          // "123.0"

Pour cette méthode de formatage, on utilise toujours CurrentCulture. Pour certaines cultures, . sera remplacé par ,.

Réponse à la question initiale:

La solution la plus simple vient de @Andrew ( here ). Donc, personnellement, je voudrais utiliser quelque chose comme ceci:

var number = 123.46;
String.Format(number % 1 == 0 ? "{0:0}" : "{0:0.00}", number)
461
Gh61

Il s'agit d'un cas d'utilisation courant avec un nombre flottant de formatage.

Malheureusement, toutes les chaînes de format d'une lettre intégrées (par exemple, F, G, N) n'atteindront pas cet objectif directement.
Par exemple, num.ToString("F2") affichera toujours 2 décimales telles que _123.40_.

Vous devrez utiliser le motif 0.## même s'il a l'air un peu prolixe.

Un exemple de code complet:

_double a = 123.4567;
double b = 123.40;
double c = 123.00;

string sa = a.ToString("0.##"); // 123.46
string sb = b.ToString("0.##"); // 123.4
string sc = c.ToString("0.##"); // 123
_
55
detale

Ancienne question mais je voulais ajouter l'option la plus simple à mon avis.

Sans milliers de séparateurs:

value.ToString(value % 1 == 0 ? "F0" : "F2")

Avec milliers de séparateurs:

value.ToString(value % 1 == 0 ? "N0" : "N2")

Le même mais avec String.Format:

String.Format(value % 1 == 0 ? "{0:F0}" : "{0:F2}", value) // Without thousands separators
String.Format(value % 1 == 0 ? "{0:N0}" : "{0:N2}", value) // With thousands separators

Si vous en avez besoin dans plusieurs endroits, j'utiliserais cette logique dans une méthode d'extension:

public static string ToCoolString(this decimal value)
{
    return value.ToString(value % 1 == 0 ? "N0" : "N2"); // Or F0/F2 ;)
}
36
Andrew

essayer

double myPrice = 123.0;

String.Format(((Math.Round(myPrice) == myPrice) ? "{0:0}" : "{0:0.00}"), myPrice);
27
Yahia

Je ne sais pas de toute façon de mettre une condition dans le spécificateur de format, mais vous pouvez écrire votre propre formateur:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
               // all of these don't work
            Console.WriteLine("{0:C}", 10);
            Console.WriteLine("{0:00.0}", 10);
            Console.WriteLine("{0:0}", 10);
            Console.WriteLine("{0:0.00}", 10);
            Console.WriteLine("{0:0}", 10.0);
            Console.WriteLine("{0:0}", 10.1);
            Console.WriteLine("{0:0.00}", 10.1);

          // works
            Console.WriteLine(String.Format(new MyFormatter(),"{0:custom}", 9));
            Console.WriteLine(String.Format(new MyFormatter(),"{0:custom}", 9.1));
            Console.ReadKey();
        }
    }

    class MyFormatter : IFormatProvider, ICustomFormatter
    {
        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            switch (format.ToUpper())
            {
                case "CUSTOM":
                    if (arg is short || arg is int || arg is long)
                        return arg.ToString();
                    if (arg is Single || arg is Double)
                        return String.Format("{0:0.00}",arg);
                    break;
                // Handle other
                default:
                    try
                    {
                        return HandleOtherFormats(format, arg);
                    }
                    catch (FormatException e)
                    {
                        throw new FormatException(String.Format("The format of '{0}' is invalid.", format), e);
                    }
            }
            return arg.ToString(); // only as a last resort
        }

        private string HandleOtherFormats(string format, object arg)
        {
            if (arg is IFormattable)
                return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
            if (arg != null)
                return arg.ToString();
            return String.Empty;
        }

        public object GetFormat(Type formatType)
        {
            if (formatType == typeof(ICustomFormatter))
                return this;
            return null;
        }
    }
}
7
Tim Hoolihan

Code simple en une ligne:

public static string DoFormat(double myNumber)
{
    return string.Format("{0:0.00}", myNumber).Replace(".00","");
}
6
Philip Stuyck

Voici une alternative à la méthode d'Uwe Keim, qui conserverait le même appel de méthode:

var example1 = MyCustomFormat(123.1);  // Output: 123.10
var example2 = MyCustomFormat(123.95); // Output: 123.95
var example3 = MyCustomFormat(123);    // Output: 123

Avec MyCustomFormat étant quelque chose comme:

public static string MyCustomFormat( double myNumber )
{
    var str (string.Format("{0:0.00}", myNumber))
    return (str.EndsWith(".00") ? str.Substring(0, strLastIndexOf(".00")) : str;
}
6
Steve

Je crains qu'il n'y ait pas de format intégré pour ce faire. Vous devrez utiliser un format différent selon que la valeur est un nombre entier ou non. Ou toujours formater à 2 décimales et manipuler la chaîne par la suite pour supprimer tout ".00" final.

5
Nikki Locke

Si aucune autre réponse ne fonctionne pour vous, c'est peut-être parce que vous liez la ContentProperty d'un contrôle dans la fonction OnLoad, ce qui signifie que cela ne fonctionnera pas:

private void UserControl_Load(object sender, RoutedEventArgs e)
{
  Bind.SetBindingElement(labelName, String.Format("{0:0.00}", PropertyName), Label.ContentProperty) 
}

La solution est simple: il existe une propriété ContentStringFormat dans le xaml. Ainsi, lorsque vous créez l'étiquette, procédez comme suit:

//if you want the decimal places definite
<Label Content="0" Name="labelName" ContentStringFormat="0.00"/>

Ou

//if you want the decimal places to be optional
<Label Content="0" Name="labelName" ContentStringFormat="0.##"/>
4
Brazizzle

Si votre programme doit être exécuté rapidement, appelez value.ToString (formatString) pour des performances de formatage de chaîne plus rapides d'environ 35% par rapport à $ "{valeur: formatString}" et à string.Format (formatString, valeur).

Les données

C# String Formatting Performance - VS2017 15.4.5

Code

using System;
using System.Diagnostics;

public static class StringFormattingPerformance
{
   public static void Main()
   {
      Console.WriteLine("C# String Formatting Performance");
      Console.WriteLine("Milliseconds Per 1 Million Iterations - Best Of 5");
      long stringInterpolationBestOf5 = Measure1MillionIterationsBestOf5(
          (double randomDouble) =>
          {
             return $"{randomDouble:0.##}";
          });
      long stringDotFormatBestOf5 = Measure1MillionIterationsBestOf5(
          (double randomDouble) =>
          {
             return string.Format("{0:0.##}", randomDouble);
          });
      long valueDotToStringBestOf5 = Measure1MillionIterationsBestOf5(
          (double randomDouble) =>
          {
             return randomDouble.ToString("0.##");
          });
      Console.WriteLine(
$@"            $""{{value:formatString}}"": {stringInterpolationBestOf5} ms
 string.Format(formatString, value): {stringDotFormatBestOf5} ms
       value.ToString(formatString): {valueDotToStringBestOf5} ms");
   }

   private static long Measure1MillionIterationsBestOf5(
       Func<double, string> formatDoubleUpToTwoDecimalPlaces)
   {
      long elapsedMillisecondsBestOf5 = long.MaxValue;
      for (int perfRunIndex = 0; perfRunIndex < 5; ++perfRunIndex)
      {
         var random = new Random();
         var stopwatch = Stopwatch.StartNew();
         for (int i = 0; i < 1000000; ++i)
         {
            double randomDouble = random.NextDouble();
            formatDoubleUpToTwoDecimalPlaces(randomDouble);
         }
         stopwatch.Stop();
         elapsedMillisecondsBestOf5 = Math.Min(
            elapsedMillisecondsBestOf5, stopwatch.ElapsedMilliseconds);
      }
      return elapsedMillisecondsBestOf5;
   }
}

Sortie de code

C# String Formatting Performance
Milliseconds Per 1 Million Iterations - Best Of 5
            $"{value:formatString}": 419 ms
 string.Format(formatString, value): 419 ms
       value.ToString(formatString): 264 ms

Références

Chaînes de format numérique personnalisées [docs.Microsoft.com]

Exemple de graphique à barres Qt Charts [doc.qt.io]

4
Neil Justice

quelque chose comme cela fonctionnera aussi:

String.Format("{0:P}", decimal.Parse(Resellers.Fee)).Replace(".00", "")
3
ekkis

Essayer:

String.Format("{0:0.00}", Convert.ToDecimal(totalPrice));
3
user1067656

Pour rendre le code plus clair que Kahia a écrit (c’est clair mais cela devient difficile lorsque vous voulez ajouter du texte) ... essayez cette solution simple.

if (Math.Round((decimal)user.CurrentPoints) == user.CurrentPoints)
     ViewBag.MyCurrentPoints = String.Format("Your current Points: {0:0}",user.CurrentPoints);
else
     ViewBag.MyCurrentPoints = String.Format("Your current Points: {0:0.0}",user.CurrentPoints);

J'ai dû ajouter la conversion supplémentaire (décimal) pour que Math.Round compare les deux variables décimales.

2
coding_is_fun

Cela a fonctionné pour moi!

String amount= "123.0000";
String.Format("{0:0.##}", amount);      // "123.00"
1
Edwin Ikechukwu