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