2010-07-03 48 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; 
}