繁体   English   中英

解析字符串浮点时精度更高

[英]Higher precision when parsing string to float

这是我在这里的第一篇文章,对不起,如果拖了一点。

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

-82.636097527336

这是我用来解析它的代码,我也在该站点上找到了(感谢!):

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

其中“ prelim [i]”只是我使用的当前数字,“度”是我的新矢量,其中包含将所有数字解析为浮点数后的所有数字。 我的问题是,在将其解析并存储为“度”后,我执行了“ std :: cout”命令并排比较两个值,并在左侧显示了这样的(旧值(字符串),值(浮动)在右侧):

-82.6361

有谁对我如何缓解这个问题并使我的数字更准确有任何见解? 我可以一个字符一个字符地使用一个切换用例,但是我认为有一种简单的方法只需几行代码即可完成。

再次感谢您,任何指点将不胜感激!

(为清楚起见,我进行了编辑以输出值)

更改为double值可以更准确地表示该值,并使用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;
}

输出:

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以所需的精度进行打印。

您不能使用简单的float来精确到小数点后12位。 直观的做法是使用doublelong double ...但您将不会拥有所需的精度。

原因是由于实数在内存中的表示。 在这里有更多信息。

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

您应该改用专用库来实现任意精度

希望这可以帮助。

暂无
暂无

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

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