简体   繁体   中英

How to convert string to double with specified number of precision in c++

How to convert string to double with specified number of precision in c++ code snippet as below:

  double value;
  CString thestring(_T("1234567890123.4"));
 value = _tcstod(thestring,NULL);

The value is coming as this:1234567890123.3999
expected value is:1234567890123.4  

Basically you can use strtod or std::stod for the conversion and then round to your desired precision. For the actual rounding, a web search will provide lots of code examples.

But the details are more complicated than you might think: The string is (probably) a decimal representation of the number while the double is binary. I guess that you want to round to a specified number of decimal digits. The problem is that most decimal floating point decimal numbers cannot be exactly represented in binary. Even for numbers like 0.1 it is not possible.

You also need to define what kind of precision you are interested in. Is it the total number of digits (relative precision) or the number of digits after the decimal point (absolute precision).

std::stod is generic and doesn't give this kind of manipulation. Thus, you have to craft something of your own, like I did below using std::stringstream and <iomanip> facilities:

double stodpre(std::string const &str, std::size_t const p) {
  std::stringstream sstrm;
  sstrm << std::setprecision(p) << std::fixed << str << std::endl;

  double d;
  sstrm >> d;

  return d;
}

Live Demo

You cannot control the precision with which a decimal number is stored. Decimal numbers are stored in binary using the floating point notation.

What you can do is to control the precision of what is displayed on outputting the number.

For example, do this to control the precision of the output to 2 digits -

std::cout << std::fixed;
std::cout << std::setprecision(2);
std::cout << value;

You can give any number for the precision.

The floating-point double type can not exactly represent the value 1234567890123.4 and 1234567890123.3999 is the best it can represent and that is what the result is. Note that floating point types (eg IEEE-754) can not exactly represent all real numbers, hence these use approximations for most cases.

To be more precise, according to IEEE-754 double-precision floating point format 1234567890123.4 is represented as the hexadecimal value of 4271F71FB04CB666 , where in binary the sign bit is 0 , the 11 exponent and 52 singificand bits are 10000100111 and 0001111101110001111110110000010011001011011001100110 respectively. So this results in the value of (-1) sign ×2 exponent ×(1.significand bits) = 1×2 40 ×1.1228329550462148311851251492043957114219 = 1234567890123.39990234375.

Note that not even a 128-bit floating point would store the value exactly. It would still result in 1234567890123.39999999999999999999991529670527456996609316774993203580379486083984375. Maybe you should instead attempt to use some fixed-point or rational number types instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM