浮动和双重比较最有效的方法是什么?

浮动和双重比较最有效的方法是什么?

比较两个double或两个float值的最有效方法是什么?

简单地这样做是不正确的:

bool CompareDoubles1 (double A, double B){
   return A == B;}

但是像这样:

bool CompareDoubles2 (double A, double B) {
   diff = A - B;
   return (diff < EPSILON) && (-diff < EPSILON);}

似乎浪费处理。

有谁知道更聪明的浮动比较器?


ITMISS
浏览 823回答 4
4回答

素胚勾勒不出你

使用任何其他建议时要格外小心。这一切都取决于背景。我花了很长时间跟踪系统中的错误,假设a==b是|a-b|<epsilon。潜在的问题是:算法中隐含的假设,if&nbsp;a==b和b==cthen&nbsp;a==c。使用相同的epsilon测量以英寸为单位的线和以mils(.001英寸)测量的线。那是a==b但是1000a!=1000b。(这就是AlmostEqual2sComplement要求epsilon或max ULPS的原因)。对于角度的余弦和线的长度,使用相同的epsilon!使用这样的比较函数对集合中的项目进行排序。(在这种情况下,使用内置C ++运算符== for double产生了正确的结果。)就像我说:这一切都取决于背景和预期的大小a和b。BTW,std::numeric_limits<double>::epsilon()是“机器epsilon”。它是1.0和下一个值之间的差值,可用双精度表示。我猜它可以在比较函数中使用,但只有在预期值小于1时才会使用。(这是对@ cdv答案的回应......)另外,如果你基本上有int算术doubles(这里我们使用双精度来保存某些情况下的int值)你的算术是正确的。例如,4.0 / 2.0将与1.0 + 1.0相同。只要您不执行导致分数(4.0 / 3.0)或不超出int大小的事情。

千万里不及你

与epsilon值的比较是大多数人所做的(即使在游戏编程中)。你应该稍微改变你的实现:bool&nbsp;AreSame(double&nbsp;a,&nbsp;double&nbsp;b){ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;fabs(a&nbsp;-&nbsp;b)&nbsp;<&nbsp;EPSILON;}编辑:Christer在最近的博客文章中添加了一堆有关此主题的精彩信息。请享用。

哔哔one

有关更深入的方法,请参阅比较浮点数。以下是该链接的代码段://&nbsp;Usable&nbsp;AlmostEqual&nbsp;function&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;AlmostEqual2sComplement(float&nbsp;A,&nbsp;float&nbsp;B,&nbsp;int&nbsp;maxUlps)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Make&nbsp;sure&nbsp;maxUlps&nbsp;is&nbsp;non-negative&nbsp;and&nbsp;small&nbsp;enough&nbsp;that&nbsp;the&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;default&nbsp;NAN&nbsp;won't&nbsp;compare&nbsp;as&nbsp;equal&nbsp;to&nbsp;anything.&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;assert(maxUlps&nbsp;>&nbsp;0&nbsp;&&&nbsp;maxUlps&nbsp;<&nbsp;4&nbsp;*&nbsp;1024&nbsp;*&nbsp;1024);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;aInt&nbsp;=&nbsp;*(int*)&A;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Make&nbsp;aInt&nbsp;lexicographically&nbsp;ordered&nbsp;as&nbsp;a&nbsp;twos-complement&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(aInt&nbsp;<&nbsp;0)&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aInt&nbsp;=&nbsp;0x80000000&nbsp;-&nbsp;aInt;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Make&nbsp;bInt&nbsp;lexicographically&nbsp;ordered&nbsp;as&nbsp;a&nbsp;twos-complement&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;bInt&nbsp;=&nbsp;*(int*)&B;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(bInt&nbsp;<&nbsp;0)&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bInt&nbsp;=&nbsp;0x80000000&nbsp;-&nbsp;bInt;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;intDiff&nbsp;=&nbsp;abs(aInt&nbsp;-&nbsp;bInt);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(intDiff&nbsp;<=&nbsp;maxUlps)&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;&nbsp;&nbsp;&nbsp;&nbsp;}
打开App,查看更多内容
随时随地看视频慕课网APP