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?
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 String? From the apex documentation: Double myDouble = 12.34; String myString = String. valueOf(myDouble);
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[].
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With