我正在尝试将浮点数转换为字符串而不进行科学(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('.');
}
答案 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
。