解析字符串到float

时间:2016-04-03 17:43:14

标签: c++ parsing

这是我在这里的第一篇文章,如果它拖了一点就很抱歉。

我正协助我的教授进行一些研究,当我解析一些需要精确到12位小数的数字时,我在精确度上遇到了一些麻烦。例如,在解析之前,这是一个我从字符串解析为整数的数字:

  

-82.636097527336

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

std::basic_string<char> str = prelim[i];
std::stringstream s_str( str );
float val;
s_str >> val;
degrees.push_back(val);

其中&#39; prelim [i]&#39;只是我当前的号码,以及&#39;度&#39;是我的新向量,在将它们解析为浮点数之后保存所有数字。我的问题是,在解析并存储在&#39;度之后,我会做一个&#39; std :: cout&#39;命令并排比较两个值,并显示如下(左侧的旧值(字符串),右侧的新值(浮点)):

  

-82.6361

有没有人能够深入了解如何缓解此问题并使我的数字更精确?我假设我可以逐字逐句地使用切换案例,但我认为只需几行代码就可以更轻松地完成它。

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

(为了清楚我输出的值而编辑)

3 个答案:

答案 0 :(得分:2)

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

请注意,内部存储并不准确;使用英特尔酷睿i7,我得到以下值:

string: -82.636097527336

float:  -82.63610076904296875

double: -82.63609752733600544161163270473480224609

因此,正如您所看到的,double正确地表示原始输入字符串的所有数字,但即便如此,它也不是非常精确,因为有一些额外的数字比您的字符串更多。

答案 1 :(得分:2)

有两个问题:

  • 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;
}

输出:

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

因此,您需要使用64位浮点数来表示输入,还要记住使用std::setprecision以所需的精度打印。

答案 2 :(得分:0)

使用简单的float,精度不能达到十二进制。直观的行动方针是使用doublelong double ......但是你不会有你需要的精确度。

原因是由于在内存中表示实数。您有更多信息here

例如。 0.02实际存储为0.01999999 ...

您应该使用专用的library for arbitrary precision

希望这有帮助。