可以用非科学格式格式化浮点数吗?

时间:2010-07-03 01:11:39

标签: .net string-formatting

我正在尝试将浮点数转换为字符串而不进行科学(1.13E-8)样式格式化。

我正在寻找“F”和“R”说明符的某种组合。我想要F,以便它不使用科学风格,但我也想要R,以便它使用尽可能少的空间来准确表示数字。

因此,给定0.000000001,字符串版本应为0.000000001。不是1E-09,而不是0.000000001000。

是否可以告诉系统“使其成为固定点,但使用必要的最小数字来准确指定数字”?

如果没有,那么一个好的解决方法是什么?我在想:使用20的精度然后如果有''那么只是砍掉尾随的0'。在字符串中。还有什么更好的吗?

编辑:

这是我一直在使用的版本。我真的希望有一个格式说明符,我可以用来做它。

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

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:1)

以下内容仅显示小数点后的有效数字,最多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

这里的关键是#能指仅在显着时输出一个数字。

希望至少可以达到你想要的目标。如果没有,您可以随时编写自定义IFormatProvider