在没有科学记数法的情况下格式化C++中的n位有效数字

Pet*_*teC 9 c++ format scientific-notation boost-format

我想将浮点值格式化为n位有效数字,但从不使用科学记数法(即使它更短).

格式规范%f不涉及有效数字,%g有时会给我科学记数法(这对我来说不合适).

我想要表格中的价值观"123", "12.3", "1.23" or "0.000000123".

有没有一种优雅的方法来使用C++或boost来做到这一点?

Bat*_*eba 12

我知道的最好的方法(并在我自己的代码中使用它)是

#include <string>
#include <math.h>
#include <sstream>
#include <iomanip>

int round(double number)
{
    return (number >= 0) ? (int)(number + 0.5) : (int)(number - 0.5);
}

std::string format(double f, int n)
{
    if (f == 0) {
        return "0";
    }            
    int d = (int)::ceil(::log10(f < 0 ? -f : f)); /*digits before decimal point*/
    double order = ::pow(10., n - d);
    std::stringstream ss;
    ss << std::fixed << std::setprecision(std::max(n - d, 0)) << round(f * order) / order;
    return ss.str();
}
Run Code Online (Sandbox Code Playgroud)

c ++ 11有std :: round所以你不需要我的新版本的编译器.

我在这里利用的技巧是通过取基数10日志来计算小数点前的位数并从你想要的精度中减去它来获得你想要的精度.

它也满足@Mats Petersson的要求,所以在所有情况下都可以使用.

我不喜欢的是初始检查为零(因此日志功能不会爆炸).建议改进/直接编辑这个答案最受欢迎.

  • 这是一个问题(我将尝试自己修复):如果_f_是10的幂并且_n_> log10 _f_,那么输出结尾将有一个额外的零.例如`format(100.0,3)`是"100.0",而它应该是"100"(或理想情况下"100",带有一个尾随小数点). (2认同)