定点数的动态格式化

Dynamic Formatting of a fixed point number

本文关键字:格式化 动态 定点数      更新时间:2023-10-16

我需要格式化一个浮点数(表示为std::string),其中输出最多有14位数字,包括整数部分和小数部分。

虽然限制为14位数字,但整数部分最多可以有14位数字(然后没有小数部分),小数部分最多可以有7位数字(然后整数部分有7位数字)

**Examples**
123
123.456
12345678901234
1234567.89
1234.5678901
1234567890123.4
1234567890123.456 // Invalid; Should be transformed to 1234567890123.4
123456789012345.6 // Invalid; Should be transformed to 12345678901234

我们的想法是保留length =< 14,其中十进制数的最大数量是7。最后,我还需要添加千个分隔符

当前方法

目前,我尝试使用小数点分割字符串并提取数字的两个部分。(如无".",另行办理)然后检查整数部分和小数部分的尺寸。

然而,由于这不是直接的,所以在某些情况下会失败。

但是我的问题是:

有没有简单的方法,让我不用这些乱七八糟的东西?

这非常简单,似乎可以根据您的规范工作。

std::string format(string str)
{
    // Are there any decimals?
    int dot = str.find(".");
    if (dot < 0)
    {
        return str.substr(0, 14);
    }
    std::string integral = str.substr(0, dot);
    size_t intlength = integral.length();
    // Too long to care about decimals?
    if (intlength >= 14)
    {
        return integral.substr(0, 14);
    }
    // Keep at most seven decimals
    std::string decimals = str.substr(dot + 1, 7);
    size_t declength = decimals.length();
    // Is concatenation short enough?
    if (intlength + declength <= 14)
    {
        return integral + "." + decimals;
    }
    return integral + "." + decimals.substr(0, 14 - integral.length());
}

您可以使用Boost.Format。下面是一个通过测试用例的示例:

#include <iostream>
#include <iomanip>
#include <boost/format.hpp>
int main()
{
    std::vector<std::string> examples = {
        "123",
        "123.456",
        "12345678901234",
        "1234567.89",
        "1234.5678901",
        "1234567890123.4",
        "1234567890123.456",
        "123456789012345.6" 
    };
    std::string format = "%1$.15s";
    for (auto example : examples)
    {
        std::cout << boost::format(format) % example << "n";
    }
}