c++ - sprintf too many/few decimals -
i must convert decimal numbers using non-scientific (ie. no mantissa/exponent/e's) character string. code looks this:
/*! \brief converts <em>xml schema decimal</em> */ char *todecimal(double val) const { const size_t nmax = 200; char *doublestr = new char[nmax]; sprintf(doublestr, "%1.6f", val); return doublestr; }
the problem when input val
1
function returns 1.000000
hoping output of 1
. also, if change code sprintf(doublestr, "%1.0f", val);
correctly outputs 1
, if input val
changed 0.000005
output 0
, , hoping output 0.000005
. want output short possible , remove unnessesary 0
's. possible sprintf
? support 3.4e +/- 38 range function.
it turns out c++ iostreams (specifically, ostringstream
) better suited task sprintf
.
use std::fixed
manipulator disable scientific notation. use std::setprecision
specify precision (number of characters after decimal dot). in case, precision of 45 places seems enough represent float
numbers.
#include <sstream> #include <string> #include <iostream> #include <iomanip> std::string convert(double x) { std::ostringstream buffer; buffer << std::fixed << std::setprecision(45) << x; std::string result = buffer.str(); return result; }
in addition, clean-up result, remove trailing zeros.
size_t = result.find_last_not_of('0'); if (result[i] != '.') ++i; result.erase(i);
note: clean-up of trailing zeros work numbers representable (like 0.75 or 0.03125): example, number 0.1 converted 0.10000000000000000555111512312578270211815834
. 1 use non-constant precision (depending on magnitude of number), tricky right.
instead, it's possible use following ugly (and slow) hack: try converting start of string double
, , cut string if result equal initial number.
size_t i; (i = 1; < result.size(); ++i) { std::istringstream cut(result.substr(0, i)); double temp; cut >> temp; // verbose syntax fit 1 line if (temp == x) // using boost::lexical_cast break; }
Comments
Post a Comment