C# C++;C中的std::setprecision# 我通过移植一些传统C++代码来获取C,并希望保持输出相同。过去是什么东西 output << std::setprecision(10) << (double) value;
但这并没有奏效。具体来说,值C# C++;C中的std::setprecision# 我通过移植一些传统C++代码来获取C,并希望保持输出相同。过去是什么东西 output << std::setprecision(10) << (double) value;,c#,C#,但这并没有奏效。具体来说,值>1将获得更多的数字。一个常见的在线建议是先进行Math.Round,但如果总长度为 10。< /代码>,这又带来了另一个有趣的EdGE Case.这个实现很好地模仿了C++的实现。然而,四舍五入并不完全正常。1267.125到6个有效数字给出了1267.12,虽然它应该是1267.13,但我知道一定有一些琐碎的东西!显然,我遗漏的关键词是。 return number.ToString("f" + figures); public static void
>1
将获得更多的数字。一个常见的在线建议是先进行Math.Round
,但如果总长度为<10
,则会添加零
因此,我总结:
// std::setprecision is not exactly the same as ":F10", mirror original behavior
static string setPrecision(double value) {
string ret = value.ToString();
// Don't just Substring(0, 11), we need to apply rounding,
// and don't always do this, we don't want to append zeroes,
// for 10 digits + period, with 0.. not counting for total
if(ret.Length > digits + 1)
ret = Math.Round(value, digits + (value < 1 ? 1 : 0) - ret.IndexOf('.')).ToString();
return ret;
}
两者都产生:
0.12345678
0.0123456781
0.1123456782
1.002345679
同时,我注意到所有的标题0似乎并不计入总数,而不仅仅是第一个
// C++
test = 0.012345678906; out << test << '\n'; // 0.01234567891
test = 0.0012345678906; out << test << '\n'; // 0.001234567891
test = 0.00012345678906; out << test << '\n'; // 0.0001234567891
// C#
test = 0.012345678906; output.WriteLine(setPrecision(test)); // 0.0123456789
test = 0.0012345678906; output.WriteLine(setPrecision(test)); // 0.0012345679
test = 0.00012345678906; output.WriteLine(setPrecision(test)); // 0.0001234568
<代码> /C++
试验=0.012345678906;你指的是什么。计算起来其实很容易:
public static string FormatSignificantFigures(double number, int figures)
{
int e = 0;
while (number >= 10.0)
{
e += 1;
number /= 10;
}
while (number < 1.0)
{
e -= 1;
number *= 10;
}
figures--;
number = Math.Round(number, figures);
figures += 0 - e;
while (e > 0)
{
number *= 10;
e -= 1;
}
while (e < 0)
{
number /= 10;
e += 1;
}
if (figures < 0)
{
figures = 0;
}
return number.ToString($"f{figures}");
}
测试代码为:
public static void _Main(string[] args)
{
double[] numbers = new double[] { 0.012345678906, 0.0012345678906, 0.00012345678906, 0.123456789012, 1.234567890124, 12.345678901234, 123.45678901234, 1234.5678901234, 12345.678901234 };
foreach (double number in numbers)
{
Console.WriteLine($"{number}: {FormatSignificantFigures(number, 3)}");
}
}
结果:
注意:这是一个快速的答案,我将把其中的一些提取到另一个函数中,该函数不会立即返回字符串,但这应该可以让您开始了。听起来您只是想用特定数量的有效数字打印数字。您可以简单地使用G格式字符串来指定要使用的位数
output.Write("{0:G10}", value);
我不完全清楚你想做什么。你能给我们一些输入和输出的例子,让我把它拼凑起来吗?总结一下:在逗号后面显示10个数字,去掉尾随的零?我认为在逗号之前或之后显示10个非零数字,不带尾随的零,是一个更好的总结。你可能需要刷新页面,我意外地得到了一个零。我对C#standard库不太了解,无法帮助您,但是。无论如何,我不确定这是问这个问题的正确地方,因为这是一个非常特定于语言/库的问题。也许你会得到关于StackOverflow的更好的反馈。我刚刚对它进行了一次旋转,但注意到
0.12345678
将数字设置为10
,结果是0.1234567800
-它附加了零。所以我现在还不打算接受这个答案。但有趣的方法是,我会去尝试一下。@meeuwise所以只需使用returnnumber.ToString($“f{figures}”).TrimEnd(新字符[]{0'})代码>我想你会中断打印10
。我想仔细检查并注意到这产生了代码> 10。< /代码>,这又带来了另一个有趣的EdGE Case.这个实现很好地模仿了C++的实现。然而,四舍五入并不完全正常。1267.125到6个有效数字给出了1267.12,虽然它应该是1267.13,但我知道一定有一些琐碎的东西!显然,我遗漏的关键词是。
return number.ToString("f" + figures);
public static void _Main(string[] args)
{
double[] numbers = new double[] { 0.012345678906, 0.0012345678906, 0.00012345678906, 0.123456789012, 1.234567890124, 12.345678901234, 123.45678901234, 1234.5678901234, 12345.678901234 };
foreach (double number in numbers)
{
Console.WriteLine($"{number}: {FormatSignificantFigures(number, 3)}");
}
}
0.012345678906: 0.0123
0.0012345678906: 0.00123
0.00012345678906: 0.000123
0.123456789012: 0.123
1.234567890124: 1.23
12.345678901234: 12.3
123.45678901234: 123
1234.5678901234: 1230
12345.678901234: 12300
output.Write("{0:G10}", value);