Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert 'double' to 'string' in user-friendly form

Tags:

c++

string

double

i have the following problem: customer want to present double type to a string by an optimal way. it need to be converted to string and showed on a form(sms, table and other).

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;

The code for converting is a performance critical, it means that no std::stringstream + setprecision() should be used.

It will be great to implement params 'precision' as argument of my toStringNew() function, but this improvements may critically affects all our system, and we are planning implement it in the next release. But this problem is actual now.
I wrote the following code:

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;
}

This works at 1,5 times faster than boost::spirit::karma::generate() for double type.

Can you give me some advices how to satisfy my customer?

like image 980
Sergey_Ivanov Avatar asked Jun 08 '15 13:06

Sergey_Ivanov


People also ask

What is string format for double?

String. format("%4.3f" , x) ; It means that we need total 4 digits in ans , of which 3 should be after decimal . And f is the format specifier of double .

How do I convert a double to a string in Salesforce?

How do I convert a Double to String? From the apex documentation: Double myDouble = 12.34; String myString = String. valueOf(myDouble);

How do I convert a double to a char?

A double cannot be converted to a char*. If you're simply trying to get a string representation of the double, you're going to have to convert it to a char array. A function accepting a char* will accept a char[].


1 Answers

I would look at the C++ String Toolkit Library. I have used it for parsing and number conversion and it has shown to be very fast.

#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;
}
like image 170
DannyK Avatar answered Sep 22 '22 22:09

DannyK