web-dev-qa-db-fra.com

C # Double - Mise en forme ToString () avec deux décimales, mais sans arrondi

Comment formater une Double en une String en C # afin de n’avoir que deux décimales?

Si j'utilise String.Format("{0:0.00}%", myDoubleValue), le nombre est alors arrondi et je souhaite un simple tronquer sans arrondir. Je veux aussi que la conversion en String soit sensible à la culture.

140
kjv

J'utilise les éléments suivants:

double x = Math.Truncate(myDoubleValue * 100) / 100;

Par exemple:

Si le nombre est 50.947563 et que vous utilisez ce qui suit, voici ce qui se passera:

- Math.Truncate(50.947563 * 100) / 100;
- Math.Truncate(5094.7563) / 100;
- 5094 / 100
- 50.94

Et votre réponse est tronquée. Pour formater la chaîne, procédez comme suit:

string s = string.Format("{0:N2}%", x); // No fear of rounding and takes the default number format
187
Kyle Rozendo

Ce qui suit arrondit les nombres, mais n’affiche que 2 décimales au maximum (en supprimant les zéros de fin), grâce à .##.

decimal d0 = 24.154m;
decimal d1 = 24.155m;
decimal d2 = 24.1m;
decimal d3 = 24.0m;

d0.ToString("0.##");   //24.15
d1.ToString("0.##");   //24.16 (rounded up)
d2.ToString("0.##");   //24.1  
d3.ToString("0.##");   //24

http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/

92
Brian Ogden

Je vous suggère de commencer par tronquer, puis de formater:

double a = 123.4567;
double aTruncated = Math.Truncate(a * 100) / 100;
CultureInfo ci = new CultureInfo("de-DE");
string s = string.Format(ci, "{0:0.00}%", aTruncated);

Utilisez la constante 100 pour tronquer 2 chiffres; utilisez un 1 suivi de autant de zéros que de chiffres après la virgule souhaitée. Utilisez le nom de culture dont vous avez besoin pour ajuster le résultat de la mise en forme.

32
CesarGon

Méthode la plus simple, utilisez des chaînes de format numériques:

double total = "43.257"
MessageBox.Show(total.ToString("F"));

j'utilise price.ToString("0.00") pour obtenir les 0 premiers

9
CMS

La fonction c #, telle qu'exprimée par Kyle Rozendo:

string DecimalPlaceNoRounding(double d, int decimalPlaces = 2)
{
    d = d * Math.Pow(10, decimalPlaces);
    d = Math.Truncate(d);
    d = d / Math.Pow(10, decimalPlaces);
    return string.Format("{0:N" + Math.Abs(decimalPlaces) + "}", d);
}
5
maxp

Cela fonctionne pour moi

string prouctPrice = Convert.ToDecimal(String.Format("{0:0.00}", Convert.ToDecimal(yourString))).ToString();
5
Zain Ali

Pourquoi ne pas ajouter une décimale supplémentaire à arrondir puis à jeter:

var d = 0.241534545765;
var result1 = d.ToString("0.###%");

var result2 = result1.Remove(result1.Length - 1);
4
user3638471

Je sais que c'est un vieux fil, mais je viens de le faire. Alors que les autres approches fonctionnent ici, je cherchais un moyen simple d’affecter de nombreux appels à string.format. Donc, ajouter le Math.Truncate à tous les appels n'était pas vraiment une bonne option. De plus, une partie du formatage étant stockée dans une base de données, la situation est encore pire.

Ainsi, j'ai créé un fournisseur de format personnalisé qui me permettrait d'ajouter une troncature à la chaîne de formatage, par exemple:

string.format(new FormatProvider(), "{0:T}", 1.1299); // 1.12
string.format(new FormatProvider(), "{0:T(3)", 1.12399); // 1.123
string.format(new FormatProvider(), "{0:T(1)0,000.0", 1000.9999); // 1,000.9

L'implémentation est assez simple et peut facilement être étendue à d'autres exigences.

public class FormatProvider : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        if (formatType == typeof (ICustomFormatter))
        {
            return this;
        }
        return null;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        if (arg == null || arg.GetType() != typeof (double))
        {
            try
            {
                return HandleOtherFormats(format, arg);
            }
            catch (FormatException e)
            {
                throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
            }
        }

        if (format.StartsWith("T"))
        {
            int dp = 2;
            int idx = 1;
            if (format.Length > 1)
            {
                if (format[1] == '(')
                {
                    int closeIdx = format.IndexOf(')');
                    if (closeIdx > 0)
                    {
                        if (int.TryParse(format.Substring(2, closeIdx - 2), out dp))
                        {
                            idx = closeIdx + 1;
                        }
                    }
                    else
                    {
                        throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
                    }
                }
            }
            double mult = Math.Pow(10, dp);
            arg = Math.Truncate((double)arg * mult) / mult;
            format = format.Substring(idx);
        }

        try
        {
            return HandleOtherFormats(format, arg);
        }
        catch (FormatException e)
        {
            throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
        }
    }

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

Ce qui suit ne peut être utilisé que pour l'affichage qui utilise la propriété de String ..

double value = 123.456789;
String.Format("{0:0.00}", value);
1

Pour ce qui vaut la peine, pour afficher la devise, vous pouvez utiliser "C":

double cost = 1.99;
m_CostText.text = cost.ToString("C"); /*C: format as currentcy */

Sortie: $1.99

1

Vous pouvez également écrire votre propre IFormatProvider , bien que je suppose que vous devrez éventuellement penser à un moyen de procéder à la troncature.

Le .NET Framework prend également en charge la mise en forme personnalisée. Cela implique généralement la création d'une classe de formatage qui implémente à la fois IFormatProvider et ICustomFormatter . (msdn)

Au moins, ce serait facilement réutilisable.

Il y a un article sur la façon d'implémenter votre propre IFormatProvider/ICustomFormatter ici chez CodeProject . Dans ce cas, "étendre" un format numérique existant pourrait être le meilleur choix. Ça n'a pas l'air trop dur.

0
Benny Jobigan

Notez également le CultureInformation de votre système. Voici ma solution sans arrondir.

Dans cet exemple, il vous suffit de définir la variable MyValue comme double. En conséquence, vous obtenez votre valeur formatée dans la variable chaîne NewValue.

Remarque - Définissez également l'instruction C # using:

using System.Globalization;  

string MyFormat = "0";
if (MyValue.ToString (CultureInfo.InvariantCulture).Contains (CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator))
   {
      MyFormat += ".00";
   }

string NewValue = MyValue.ToString(MyFormat);
0
Daniel

Solution:

var d = 0.123345678; 
var stringD = d.ToString(); 
int indexOfP = stringD.IndexOf("."); 
var result = stringD.Remove((indexOfP+1)+2);

(indexOfP + 1) +2 (ce nombre dépend du nombre que vous souhaitez conserver. Je lui en donne deux parce que le propriétaire de la question le souhaite.)

0
劉鎮瑲

J'ai eu ce problème avec xamarin et résolu avec:

porcent.ToString("0.##"+"%")
0
Diego Sanchez