2010-07-03 63 views
3

我試圖將浮動轉換爲字符串而沒有得到科學(1.13E-8)樣式格式。可能以非科學格式格式化浮點數?

我正在尋找「F」和「R」說明符的組合。我希望F不使用科學風格,但我也希望R能夠使用盡可能小的空間來精確地表示數字。

因此給出0.000000001,字符串版本應該是0.000000001。不是1E-09,而不是0.000000001000。

是否可以告訴系統「使其固定點,但使用必要的最小數字來精確指定數字」?

如果不是,一個好的解決方法是什麼?我在想:使用20的精確度,然後只是在'0'後面跟蹤0。在字符串中。有什麼更好的?

編輯:

這是我一直在使用的版本。我真的希望能有一個格式說明符,我可以用它來做到這一點。

​​

回答

1

以下將只顯示小數點後的有效數字,最多10天。

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 

的這裏關鍵的是,如果是顯著#能指僅輸出數字。

希望至少能達到你想要的水平。如果沒有,你可以隨時寫一個自定義IFormatProvider

1

請注意,「準確指定數字」可能是不可能的。該數字可能涉及基數爲2的重複。請考慮如何在基數10中重複1/3作爲0.33333333...。這也發生在基地2,只有更糟。但是,您可以使用「r」來獲得一個往返的值。

使用"F20"然後修整不會產生相同的結果如"r"格式移位小數位。在Math.PI上,您的代碼產生3.14159265358979。往返應該是3.1415926535897931

例如,下面是如何移動"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; 
}