Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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++_Comparison_Precision - Fatal编程技术网

C++ 补偿双精度/浮动精度

C++ 补偿双精度/浮动精度,c++,comparison,precision,C++,Comparison,Precision,我已经编写了一个数学计算器,它从用户那里获取一个字符串并对其进行解析。它使用double保存计算时涉及的所有值。解决后,我将其打印出来,并使用std::setprecision()确保正确输出(例如0.9999999将在打印输出时变为1) 返回将被输出的字符串: //return true or false if this is in the returnstring. if (returnString.compare("True") == 0 || returnString.compare(

我已经编写了一个数学计算器,它从用户那里获取一个字符串并对其进行解析。它使用double保存计算时涉及的所有值。解决后,我将其打印出来,并使用
std::setprecision()
确保正确输出(例如
0.9999999
将在打印输出时变为
1

返回将被输出的字符串:

//return true or false if this is in the returnstring.

if (returnString.compare("True") == 0 || returnString.compare("False") == 0) return returnString;

    //create stringstream and put the answer into the returnString.
    std::stringstream stream;
    returnString = std::to_string(temp_answer.answer);

    //write into the stream with precision set correctly.
    stream << std::fixed << std::setprecision(5) << temp_answer.answer;


    return stream.str();

我认为需要进行某种舍入,但我不能100%确定如何正确完成。如果已经解决了这个问题,请原谅我-我无法通过搜索找到太多。谢谢!

假设
答案是
双倍的
,请替换这个

lhs_ret.get().answer == rhs_ret.get().answer

abs(lhs_ret.get().answer-rhs_ret.get().answer)
其中,
TOL
是一个合适的公差值

绝不应将浮点数与
==
进行比较,而应检查绝对差值是否小于给定公差

有一个困难需要提及:双精度约为16位小数。因此,您可以设置
TOL=1.0e-16
。这仅在数字小于1时有效。对于16位数字,这意味着公差必须与1一样大


因此,要么您假设您的数字小于say
10e8
,并使用相对较大的公差,如
10e-8
,要么您需要做更复杂的事情。

假设
answer
是一个
double
,则将其替换

lhs_ret.get().answer == rhs_ret.get().answer

abs(lhs_ret.get().answer-rhs_ret.get().answer)
其中,
TOL
是一个合适的公差值

绝不应将浮点数与
==
进行比较,而应检查绝对差值是否小于给定公差

有一个困难需要提及:双精度约为16位小数。因此,您可以设置
TOL=1.0e-16
。这仅在数字小于1时有效。对于16位数字,这意味着公差必须与1一样大

因此,要么您假设您的数字小于say
10e8
,并使用相对较大的公差,如
10e-8
,要么您需要做更复杂的事情。

首先考虑:

作为基本经验法则,
double
将是一个大约16dp的值,其中dp是小数位,或
1.0e-16
。您需要注意,这只适用于小于一(1)的数字IE for 10.n您必须围绕这一事实操作,您只能有15dp,例如:
10.0e-15
等等……由于计算机以2为基数计数,而人们以10为基数计数,一些值永远无法在“大多数”现代操作系统使用的位范围内正确表示

用二进制或基数2表示0.1是无限长的,这一事实可以突出说明这一点

因此,您永远不应该通过
=
运算符比较有理数。相反,通常使用的“转到”解决方案是:

您实现了一个“足够接近”的解决方案。即:您将epsilon定义为一个值,例如:
epsilon=0.000001
,并且您声明如果
(值a-value b)
。我们要说的是
如果a-b在e
之内,对于我们程序的所有意图和目的,它的接近程度足以被视为true

现在选择epsilon的值,这完全取决于你的目的需要有多精确。例如,你可以假设与2D侧滚平台游戏相比,你需要高水平的结构工程精度

您的解决方案是替换代码的第7行:

(lhs_ret.get().answer==rhs_ret.get().answer)

abs(lhs_ret.get().answer-rhs_ret.get().answer)
其中abs是绝对值。即忽略值的符号
lhs

关于更多的内容,我强烈推荐这节麻省理工学院开放式课程,它以一种易于理解的方式来解释

首先考虑:

作为基本经验法则,
double
将是一个大约16dp的值,其中dp是小数位,或
1.0e-16
。您需要注意,这只适用于小于一(1)的数字IE for 10.n您必须围绕这一事实操作,您只能有15dp,例如:
10.0e-15
等等……由于计算机以2为基数计数,而人们以10为基数计数,一些值永远无法在“大多数”现代操作系统使用的位范围内正确表示

用二进制或基数2表示0.1是无限长的,这一事实可以突出说明这一点

因此,您永远不应该通过
=
运算符比较有理数。相反,通常使用的“转到”解决方案是:

您实现了一个“足够接近”的解决方案。即:您将epsilon定义为一个值,例如:
epsilon=0.000001
,并且您声明如果
(值a-value b)
。我们要说的是
如果a-b在e
之内,对于我们程序的所有意图和目的,它的接近程度足以被视为true

现在选择epsilon的值,这完全取决于你的目的需要有多精确。例如,你可以假设与2D侧滚平台游戏相比,你需要高水平的结构工程精度

您的解决方案是替换代码的第7行:

(lhs_ret.get().answer==rhs_ret.get().answer)

abs(lhs_ret.get().answer-rhs_ret.get().answer)
其中abs是绝对值。即忽略值的符号
lhs

关于更多的内容,我强烈推荐这节麻省理工学院开放式课程,它以一种易于理解的方式来解释

你知道的
double
abs(lhs_ret.get().answer - rhs_ret.get().answer) < TOL