c++ - 如何以用户友好的形式将 'double' 转换为 'string'

标签 c++ string double

我有以下问题: 客户希望以最佳方式将 double 类型呈现给 string。它需要转换为字符串并显示在表单(短信、表格等)上。

100000000.949999 needs to be converted in 100000000.950;
10.000000001 -> 10.0;
100000000000000.19292 -> 1e+14;
1000.123456789 -> 1000.123;
0.00001 -> 0.0;

转换代码对性能至关重要,这意味着不应使用 std::stringstream + setprecision()

将 params 'precision' 实现为我的 toStringNew() 函数的参数会很棒,但这种改进可能会对我们的所有系统产生严重影响,我们计划在下一个版本中实现它。 但这个问题现在是现实的。
我写了以下代码:

inline bool toStringNew(std::string& str, double const& value)
{
    static const char *zero_double_str = "0.0";
    static const double zero_double_limit = 0.001;
    static const int max_double_prec_symbol = 13;
    static const int max_fract_num = 3;
    static const int max_fract_mul = pow(10, max_fract_num);
    str.clear();
    //get digits of integer part
    double fabs_value = fabs(value);
    int64_t len = log10(fabs_value);
    //Round 2 zero
    if(len <= 0) //it means that only fraction part is present
    {
        if(fabs_value < zero_double_limit)
        {
            str = zero_double_str;
            return true;
        }
        //use default
        return boost::spirit::karma::generate(std::back_inserter(str), value);
    }
    else if(len > max_double_prec_symbol)   //default
    {
        return boost::spirit::karma::generate(std::back_inserter(str), value);
    }
    //cast to integer
    int64_t i = static_cast<int64_t>(value);
    //cast fract to integer
    int64_t fract_i = static_cast<int64_t>(round((value - i)* max_fract_mul));
    //reserve string memory
    size_t str_len = len + 1 +  max_fract_num + (value > 0 ? 0 : 1) + 1; 
    str.reserve(str_len);
    //convert integer
    boost::spirit::karma::generate(std::back_inserter(str), i);
    str+='.';
    //convert fract
    if(fract_i > 0)
    {
        str+='.';
        int64_t fract_i_len = log10(fract_i);
        //fill zero before: 0.001 -> 1 -> 001
        while(++fract_i_len < max_fract_num)
        {
            str += '0';
        }
        //remove zero after: 010 -> 01
        while(!(fract_i % 10))
        {
            fract_i = fract_i / 10;
        }
        boost::spirit::karma::generate(std::back_inserter(str), fract_i);
    }
    boost::spirit::karma::generate(std::back_inserter(str), fract_i);
    return true;
}

对于 double 类型,这比 boost::spirit::karma::generate() 快 1.5 倍。

你能给我一些如何让我的客户满意的建议吗?

最佳答案

我会查看 C++ String Toolkit Library .我已经将它用于解析和数字转换,并且速度非常快。

#include <cmath>
#include <strtk.hpp>
#include <iostream>
using namespace std;

int main ( int argc, char **argv ) 
{
   double pi = M_PI;
   std::cout << strtk::type_to_string<double>( pi ) << std::endl;
   return 0;
}

关于c++ - 如何以用户友好的形式将 'double' 转换为 'string',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30710774/

相关文章:

C++ 返回空指针

arrays - 如何将字符串转换为没有空格的数组

c++ - clang++ 直接将字符串序列化到二进制文件就可以了吗?

java - 如何将 XML 文件中的 x 和 y 坐标解析为 Java 中的 Point2D 数组?

c++ - 打印 double 的整个非小数部分

c++ - 我可以访问没有任何前向声明的类/结构上的静态成员函数吗?

python - 使用 Python 的 C++ 扩展了解内存泄漏

c++ - 我可以在 IOS 上使用 tempnam 吗?

java - 如何将从 sha1 字节数组生成的字符串返回到该字节数组?

c# - 任何等效于 C# 的 "extended"?