I want the value in valDouble to be exactly "0.03456".
That's not possible, unless you target a system whose double floating point representation can represent that number.
There exists no representation for 0.03456 in the ubiquitous IEEE 754 binary64 standard which your CPU probably uses. The closest representable number is 3.45600000000000004418687638008E-2. That's the number that you should get whether you use strtod
, stod
or a character stream to convert the string.
Is there a way it can be achieved?
In order to represent 0.03456 exactly on a system whose floating point cannot represent that number, you must use integers to represent the number. You can implement arbitrary precision arithmetic, fixed-point arithmetic or a decimal floating point using integers.
Basically the value ... needs to be rounded to say "0.03456".
You can round the output when you convert the non-exact float into a string:
std::cout << std::setprecision(4) << 0.03456;
BTW, the value in strDouble changes all the time. So it's not possible to set precision to say 5 or something like that.
Then you have to record the number of significant digits in the input string in order to use the same precision in output.
Here's an example function for that purpose:
template<class Range>
auto get_precision(const Range& r)
{
auto is_significant = [](auto c) {
return std::isdigit(c) && c != '0';
};
auto first = std::find_if(std:: begin(r), std:: end(r), is_significant);
auto last = std::find_if(std::rbegin(r), std::rend(r), is_significant).base();
return std::count_if(first, last, [](auto c) {
return std::isdigit(c);
});
}
// demo
std::cout << get_precision("0.03456"); // 4