2010-07-03 12 views
3

J'essaye de convertir un flotteur en chaîne sans obtenir le formatage de style scientifique (1.13E-8).Possibilité de formater un flottant dans un format non scientifique?

Je cherche une combinaison des spécificateurs "F" et "R". Je veux le F pour qu'il n'utilise pas le style scientifique, mais je veux aussi le R pour qu'il utilise le moins d'espace possible pour représenter exactement le nombre.

Donc, étant donné 0,000000001, la version de la chaîne doit être 0,000000001. Pas 1E-09, et pas 0.000000001000.

Est-il possible de dire au système "le rendre à point fixe, mais utiliser les chiffres minimum nécessaires pour spécifier exactement le nombre"?

Sinon, que serait une bonne solution de contournement? Je pensais: utilisez une précision de 20, puis tirez simplement sur 0 s'il y a un '.' dans la chaîne. Quelque chose de mieux?

Edit:

Voici la version que je l'ai utilisé. J'espérais vraiment qu'il y aurait un spécificateur de format que je pourrais utiliser pour le faire à la place.

var s = f.ToString("F20"); 
if (s.Contains(".")) 
{ 
    s = s.TrimEnd('0').TrimEnd('.'); 
} 

Répondre

1

Les éléments suivants affichent uniquement les chiffres significatifs après la virgule, jusqu'à 10 d.

var format = "#0.##########"; 

string.Format(1.23, format); 
// 1.23 

string.Format(1.23456, format); 
// 1.23456 

string.Format(1.230045, format); 
// 1.230045 

string.Format(1.2345678912345, format); 
// 1.2345678912 

La clé ici est que le # signifiant ne sort que si un chiffre est significative.

Espérons que cela va un peu vers ce que vous voulez, au moins. Sinon, vous pouvez toujours écrire un IFormatProvider personnalisé.

1

Notez que "spécifier exactement le nombre" peut ne pas être possible. Le nombre pourrait impliquer la répétition dans la base 2. Pensez à comment 1/3 se répète dans la base 10 comme 0.33333333.... Cela arrive également en base 2, mais pire. Cependant, vous pouvez utiliser "r" pour obtenir une valeur qui fera l'aller-retour.

aide "F20" puis coupe ne sera pas produire le même résultat que déplacer la virgule dans le format "r". Sur Math.PI, votre code produit 3.14159265358979. L'aller-retour devrait être 3.1415926535897931. Par exemple, voici comment vous pouvez déplacer le point décimal sur le format "r"

static string FormatMinDigits(double d) 
{ 
    String r = d.ToString("r", System.Globalization.CultureInfo.InvariantCulture); 
    if (Double.IsInfinity(d) || Double.IsNaN(d)) 
     return r; 
    String us = r.TrimStart('-'); 
    int epos = us.IndexOf('E'); 
    string mantissa; 
    int exponent; 
    if (epos == -1) 
    { 
     mantissa = us; 
     exponent = 0; 
    } 
    else 
    { 
     mantissa = us.Substring(0, epos); 
     exponent = Int32.Parse(us.Substring(epos + 1)); 
    } 
    int dotPos = mantissa.IndexOf('.'); 
    if (dotPos == -1) 
     dotPos = mantissa.Length; 
    mantissa = mantissa.Replace(".", ""); 
    string s; 
    if (exponent > 0) 
    { 
     if (exponent + dotPos - mantissa.Length > 0) 
      mantissa += new String('0', exponent + dotPos - mantissa.Length); 
     s = mantissa.Insert(exponent + dotPos, ".").TrimEnd('.'); 
    } 
    else if (exponent < 0) 
    { 
     if (-(exponent + dotPos) > 0) 
      mantissa = new String('0', -(exponent + dotPos)) + mantissa; 
     s = mantissa.Insert(0, "0."); 
    } 
    else 
     s = mantissa.Insert(dotPos, ".").TrimEnd('.'); 
    if (d < 0) 
     s = '-' + s; 
    if (double.Parse(s, System.Globalization.CultureInfo.InvariantCulture) != d) // Since format "r", it should roundtrip. 
     throw new Exception(string.Format("Internal error in FormatMinDigits: {0:r}", r)); 
    return s; 
} 
Questions connexes