将浮点数字格式化为具有可选小数点的有限大小的字符数组



我需要打印出固定字符数的浮点数字。这是在一个严格基于文本的数据协议中使用的(是的,我知道(。小数包含在字符计数中。忽略null终止符。没有最小填充要求。小数精度可以是0到(缓冲区大小-2(,而实数的最大数目可以是0和缓冲区大小。最小值和最大值箝位以防止真正超出范围的数字是在该问题的外部处理的。

假设缓冲区大小为6,强制最小值和最大值为(0.0001和999999(的示例:

注释只有5个数字被保留,因为没有小数+值的空间
原始缓冲区(6个字符(
12445.11897784 1245
8846.51548 8846.5
4.54631888315 4.5463
7651 7651
0.87457 。87457 0.8746也是可以接受的

这里有一个C++17版本:

#include <iostream>
#include <charconv>
std::string to6(float f) {
std::string s;
s.resize(10);
auto ec = std::to_chars(s.data(), s.data() + s.size(), f, std::chars_format::fixed);
s.resize(6);
if (s.back() == '.')
s.resize(5);
return s;
}
int main()
{
std::cout << to6(12445.11897784) << std::endl;
std::cout << to6(8846.51548) << std::endl;
std::cout << to6(4.54631888315) << std::endl;
std::cout << to6(7651) << std::endl;
std::cout << to6(0.87457) << std::endl;
return 0;
}

注意:我没有检查错误,因为

用于防止真正超出范围的数字的最小值和最大值箝位由该问题的外部处理。

看起来很简单:

  1. 如果数字大于10000
    1. 正常打印,无数字%.0f
  2. 如果一个数字大于1000
    1. 用逗号%.1f后的一位数字打印
  3. 如果一个数字大于100
    1. 用逗号%.2f后的两位数字打印
  4. 如果一个数字大于102.逗号%.3f后用3位数字打印
  5. 如果。。。1.
    1. 。。。%.4f
  6. 其他
    1. %.5f
    2. 删除前导零

注意舍入!示例编号9.999999低于10,但它将打印为10.000。正因为如此:

  1. 首先将所需精度最高的数字%.5f打印到字符串中
  2. 然后计算结果字符串中逗号之前的数字
  3. 然后进行上述比较";如果一个数字大于100〃;在逗号前的数字计数上,而不是实际数字
  4. 将字符串修剪为逗号后所需的位数

Ie。在打印后,而不是打印前,处理字符串中正确取整的数字,这样可以防止在转换为字符串时更改数字。

最新更新