Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将字符串解析为浮点时的精度更高_C++_Parsing - Fatal编程技术网

C++ 将字符串解析为浮点时的精度更高

C++ 将字符串解析为浮点时的精度更高,c++,parsing,C++,Parsing,这是我在这里的第一篇文章,如果有点拖拉,很抱歉 我正在帮助我的教授做一些研究,当我解析一些需要精确到小数点后12位的数字时,我在精度方面遇到了一些问题。例如,在解析之前,我正在将一个数字从字符串解析为整数: -82.636097527336 下面是我用来解析它的代码,我也在这个网站上找到了(谢谢!) std::basic_string str=prelim[i]; 标准:stringstream s_str(str); 浮动增值税; s_str>>val; 度。推回(val); 其中,“pre

这是我在这里的第一篇文章,如果有点拖拉,很抱歉

我正在帮助我的教授做一些研究,当我解析一些需要精确到小数点后12位的数字时,我在精度方面遇到了一些问题。例如,在解析之前,我正在将一个数字从字符串解析为整数:

-82.636097527336

下面是我用来解析它的代码,我也在这个网站上找到了(谢谢!)

std::basic_string str=prelim[i];
标准:stringstream s_str(str);
浮动增值税;
s_str>>val;
度。推回(val);
其中,“prelim[i]”只是我当前使用的数字,“degrees”是我的新向量,它保存了解析为浮点后的所有数字。我的问题是,在解析并存储在“度”中之后,我执行了一个“std::cout”命令,并排比较这两个值,并显示如下(旧值(字符串)在左侧,新值(浮点)在右侧):

-82.6361

有没有人对我如何缓解这个问题、使我的数字更精确有什么见解?我想我可以一个字符接一个字符,使用一个switch case,但我认为有一种更简单的方法,只需要几行代码就可以做到这一点

再次,提前感谢您,任何指点都将不胜感激


(为了清楚地了解我是如何输出值而编辑的)

使用简单的
浮点数,精度不能达到12位小数。直观的做法是使用
double
long double
。。。但是,您的计算机将无法达到您需要的精度

原因是内存中的实数表示。你有更多的信息

比如说。0.02实际上存储为0.0199999

您应该使用专用的


希望这有帮助。

更改为
双精度
,以更准确地表示值,并使用std::setprecision(30)或更高的精度来显示尽可能多的内部表示

请注意,内部存储并不精确;使用Intel Core i7,我得到了以下值:

string: -82.636097527336

float:  -82.63610076904296875

double: -82.63609752733600544161163270473480224609

因此,正如您所看到的,double正确地表示原始输入字符串的所有数字,但即使如此,它也不太准确,因为字符串中还有一些额外的数字。

有两个问题:

  • 32位浮点对于14位十进制数字没有足够的精度。从32位浮点可以得到大约7位十进制数字,因为它有一个23位二进制尾数。一个64位浮点(
    double
    )有52位尾数,这给了你大约16位十进制数字,就足够了
  • 默认情况下,使用
    cout
    打印将打印六位十进制数字
下面是一个小程序来说明区别:

#include <iomanip>
#include <iostream>
#include <sstream>

int main(int, const char**)
{
  float parsed_float;
  double parsed_double;
  std::stringstream input("-82.636097527336 -82.636097527336");

  input >> parsed_float;
  input >> parsed_double;

  std::cout << "float printed with default precision: "
            << parsed_float << std::endl;

  std::cout << "double printed with default precision: "
            << parsed_double << std::endl;

  std::cout << "float printed with 14 digits precision: "
            << std::setprecision(14) << parsed_float << std::endl;

  std::cout << "double printed with 14 digits precision: "
            << std::setprecision(14) << parsed_double << std::endl;

  return 0;
}

因此,您需要使用64位浮点来表示输入,但也要记住使用所需的精度进行打印。

问题在于细节:“它出来了”到底意味着什么?阅读维基百科关于浮点算术的文章,了解为什么不能从
浮点
中获得12位小数精度。您还将了解如何处理此问题。您使用什么代码打印浮点?可能是因为您打印的精度有限。另请参见。我在推回所有数字并将它们并排比较后执行“std::cout”命令,计算后的数字精度较低,如上所示。单浮点精度是有限的,您可以在此处进行测试:。您的号码由
110000101010010101000101111
表示为二进制,大约表示
-82.6361
。哇,谢谢!这100%解决了我的问题。作为后续,不管它被打印到控制台上的内容是什么,在我所有的计算过程中,精度仍然会保持准确吗?或者在我创建值之后,我还需要输入std::setprecision(),以向程序表明我希望它精确到某个值?好吧,如果我理解正确,只要我的值是双倍的,它们就会一直精确,它以更少的数字打印出来的唯一原因只是格式化?为了澄清:0.02不是存储为0.01999…,它由
(-1)^0b0*0b101000111101011100001010/2^23*2^(0b0111001-127)
表示,即5368709/268435456≈ 0.01999999955.
#include <iomanip>
#include <iostream>
#include <sstream>

int main(int, const char**)
{
  float parsed_float;
  double parsed_double;
  std::stringstream input("-82.636097527336 -82.636097527336");

  input >> parsed_float;
  input >> parsed_double;

  std::cout << "float printed with default precision: "
            << parsed_float << std::endl;

  std::cout << "double printed with default precision: "
            << parsed_double << std::endl;

  std::cout << "float printed with 14 digits precision: "
            << std::setprecision(14) << parsed_float << std::endl;

  std::cout << "double printed with 14 digits precision: "
            << std::setprecision(14) << parsed_double << std::endl;

  return 0;
}
float printed with default precision: -82.6361
double printed with default precision: -82.6361
float printed with 14 digits precision: -82.636100769043
double printed with 14 digits precision: -82.636097527336