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.
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.
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();
À 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
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;
}
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%
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.
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 .
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);
}
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"];
Si vous souhaitez conserver un nombre décimal, essayez l'exemple suivant:
number = Math.Floor(number * 100000000) / 100000000;
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
C'est simple.
decimal decNumber = Convert.ToDecimal(value);
return decNumber.ToString("0.####");
Testé.
À votre santé :)