这是我在这里的第一篇文章,如果它拖了一点就很抱歉。
我正协助我的教授进行一些研究,当我解析一些需要精确到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
有没有人能够深入了解如何缓解此问题并使我的数字更精确?我假设我可以逐字逐句地使用切换案例,但我认为只需几行代码就可以更轻松地完成它。
再次,提前感谢您,任何指示都将不胜感激!
(为了清楚我输出的值而编辑)
答案 0 :(得分:2)
更改为double
以更准确地表示值,并使用std :: setprecision(30)或更多来显示尽可能多的内部表示。
请注意,内部存储并不准确;使用英特尔酷睿i7,我得到以下值:
string: -82.636097527336
float: -82.63610076904296875
double: -82.63609752733600544161163270473480224609
因此,正如您所看到的,double正确地表示原始输入字符串的所有数字,但即便如此,它也不是非常精确,因为有一些额外的数字比您的字符串更多。
答案 1 :(得分:2)
有两个问题:
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
,精度不能达到十二进制。直观的行动方针是使用double
或long double
......但是你不会有你需要的精确度。
原因是由于在内存中表示实数。您有更多信息here。
例如。 0.02实际存储为0.01999999 ...
您应该使用专用的library for arbitrary precision。
希望这有帮助。