使用往返浮点到字符串
本文关键字:字符串 | 更新日期: 2023-09-27 18:33:13
我正在尝试将浮点数转换为它的字符串表示形式,而结果没有以科学记数法显示。
我第一次尝试:
ToString("0." + new string('#', 7))
但这似乎不适用于大值。例如:
float largeNumber = 12345678f;
string str = largeNumber.ToString("0." + new string('#', 7));
结果"12345680"
然后我尝试了ToString("R")
这适用于上面的大数字,但如果数字太大,它会以科学记数法显示它们。例如,5000000000f
结果为 "5E+09"
.像0.0005
这样的小数字会导致0.0004999999966
我也尝试混合 2,但在某些情况下我仍然会得到科学记数法。
我的测试程序粘贴在下面。我很欣赏会有精度问题,但我想知道我是否可以做得比我所拥有的更好?
class Program
{
static void Main(string[] args)
{
Write(0.123456789f);
Write(0.12345678f);
Write(0.1234567f);
Write(0.123456f);
Write(0.12345f);
Write(0.1234f);
Write(0.123f);
Write(0.12f);
Write(0.1f);
Write(1);
Write(12);
Write(123);
Write(1234);
Write(12345);
Write(123456);
Write(1234567);
Write(12345678);
Write(123456789);
Console.WriteLine();
float f = 5000000000f;
for (int i = 0; i < 17; ++i)
{
Write(f);
f /= 10;
}
Console.WriteLine();
f = 5000000000f;
for (int i = 0; i < 17; ++i)
{
Write(f < 1 ? f + 1 : f);
f /= 10;
}
Console.Read();
}
static void Write(float f)
{
//string str = f.ToString("0." + new string('#', 7));
//string str = f.ToString("R");
string str = Math.Abs(f) < 1 ? f.ToString("0." + new string('#', 7)) : f.ToString("R");
Console.WriteLine(str);
}
}
问题是float
只支持 7 位精度。无法在浮点数中精确表示12345678f
,因此它被转换为最接近的可表示浮点值,即12345680f
。 关键问题不是数字的大小,而是精度的位数。
此外,0.0005
不能用二进制浮点数精确表示;最接近0.0005
的 8 位二进制浮点数是 0.0004999999966
decimal
支持更高的精度,并且可以使用标准N
格式说明符精确地表示以 10 为基数的数字。
试试这个:
largeNumber.ToString("r")
您可以在此处找到可用格式的列表:http://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx
格式字符串中的0
不是零,它表示"如果非零则为数字,如果为零则为零",而"#"表示"如果非零则为数字,如果为零则为
您可以将格式f.ToString("0." + new string('#', 7))
用于大于零的数字
我刚刚在PowerShell中测试了它,它对我来说工作正常,尽管它可能使用双精度或小数:
PS C:'> $test = "{0:0.0######}"
PS C:'> $test -f 0.5
0,5
PS C:'> $test -f 0.4443423
0,4443423
PS C:'> $test -f 123.4443423
123,4443423
PS C:'> $test -f 45425123.4443423
45425123,4443423
当然,问题似乎float
精度
PS C:'> $test -f [float]45425123.4443423
45425120,0