我需要用 2 个有效数字来格式化值,但从不使用“e”符号。
预期输出:
9.3
6.6
4.6
3.2
2.3
1.6
1.1
760
520
340
200
96
0
123456 应打印为 120000。0.123456 应打印为 0.12
就上下文而言,它对每个 10^3 因子使用 SI 前缀。尝试过
std::format("{:.2g}", value);
但它会自行决定何时切换到“e”符号:
9.3
6.6
4.6
3.2
2.3
1.6
1.1
7.6e+02
5.2e+02
3.4e+02
2e+02
96
0
注意:我特别要求一种不使用 stringstream 的方法。
注意:使用f
格式说明符是错误的。它会产生小数点后 2 位数字,这是不正确的:
9.35
6.56
4.60
3.22
2.26
1.58
1.10
760.33
517.10
339.48
204.91
96.35
0.00
这是一个最小的可重现示例(带有一堆值)
#include <array>
#include <cstdio>
#include <format>
static constexpr std::array<float, 25> vals{
9349.3867f,
6558.6953f,
4600.0f,
3224.8362f,
2258.7588f,
1579.2142f,
1099.9999f,
760.32617f,
517.10278f,
339.47632f,
204.91417f,
96.3461f,
0.0f,
-96.346039f,
-204.91402f,
-339.47632f,
-517.10266f,
-760.32574f,
-1099.9999f,
-1579.2134f,
-2258.7578f,
-3224.8362f,
-4599.9985f,
-6558.6938f,
-9349.3867f
};
int main()
{
for(size_t k = 0; k != std::size(vals); ++k)
{
// None of these produce the expected result
puts(std::format("{:.2g}\n", vals[k]).c_str());
puts(std::format("{:.1e}\n", vals[k]).c_str());
puts(std::format("{:.2f}\n", vals[k]).c_str());
}
}
std::format
控制基本类型(如浮点数)的格式化方式,并且您的要求无法通过其格式规范来满足(这基本上是python 格式规范的工作方式)。但是,您可以创建自己的类型,其格式化程序遵循您想要施加的任何规则,您对 2 个有效数字的特定要求可以通过以下 constexpr 格式化程序来满足。
godbolt 演示
此格式化程序比double快近 1.5 倍
std::format
,但它不处理区域设置、宽度或对齐。(只需在写入输出时进行区域设置转换,即可轻松解决区域设置问题。)