简体   繁体   English

如何在C ++中将字符串转换为具有指定精度的双精度数

[英]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: 如何在c ++代码段中将字符串转换为具有指定精度的double,如下所示:

  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. 基本上,您可以使用strtodstd::stod进行转换,然后舍入到所需的精度。 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. 但是细节比您想象的要复杂:字符串是(可能是)数字的十进制表示形式,而double是二进制的。 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. 即使对于像0.1这样的数字,也不可能。

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. std::stod是通用的,不会进行这种操作。 Thus, you have to craft something of your own, like I did below using std::stringstream and <iomanip> facilities: 因此,您必须制作自己的东西,就像我在下面使用std::stringstream<iomanip>工具所做的那样:

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 - 例如,执行此操作可将输出的精度控制为2位数-

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. 浮点double类型不能完全表示 1234567890123.4的值,而1234567890123.3999是它可以表示的最佳值,这就是结果。 Note that floating point types (eg IEEE-754) can not exactly represent all real numbers, hence these use approximations for most cases. 请注意,浮点类型(例如IEEE-754)不能完全表示所有实数,因此在大多数情况下,它们使用近似值。

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. 为了更加精确,根据IEEE-754双精度浮点格式1234567890123.4被表示为十六进制值4271F71FB04CB666 ,其中以二进制符号位是0 ,则11指数和52 singificand位是100001001110001111101110001111110110000010011001011011001100110分别。 So this results in the value of (-1) sign ×2 exponent ×(1.significand bits) = 1×2 40 ×1.1228329550462148311851251492043957114219 = 1234567890123.39990234375. 因此,这导致(-1) 符号 ×2 指数 ×(1。有效位)的值= 1×2 40 ×1.1228329550462148311851251492043957114219 = 1234567890123.39990234375。

Note that not even a 128-bit floating point would store the value exactly. 请注意,即使是128位浮点数也无法准确存储该值。 It would still result in 1234567890123.39999999999999999999991529670527456996609316774993203580379486083984375. 仍然会导致1234567890123.39999999999999999999991529670527456996609316774993203580379486083984375。 Maybe you should instead attempt to use some fixed-point or rational number types instead. 也许您应该改为尝试使用一些定点或有理数类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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