在C++中比较双精度浮点数

4
我想确定一个点是否在圆内。所以我这样做: (x-center_x)^2 + (y-center_y)^2 < radius^2 但我的坐标是双精度浮点型,因此我认为应该使用epsilon,那么这个表达式更好吗? fabs ((x - center_x)^2 + (y - center_y)^2 - radius^2 ) < EPS

2
相关:https://dev59.com/P3VD5IYBdhLWcg3wU5-H - NathanOliver
2
你似乎认为 ^2 是将某个数平方。但事实并非如此。在C++中,^ 表示"按位异或" - http://en.cppreference.com/w/cpp/language/operator_arithmetic#Bitwise_logic_operators - Jesper Juhl
4个回答

5
使用<>进行比较时,您不需要 epsilon,这些很好。 相反,需要用它来代替==。 在您的情况下,您只是将一小部分添加到半径上,这可能是不想要的。 还要注意^pow(a, b)不同。

谢谢,我知道我应该在==中使用EPS,但一直想知道 <> 的用法。这让我清楚了! 附言:我知道我不能使用^来表示指数:P - Gigata
在编程中,最好使用 x*x + y*y 而不是 pow(x, 2) + pow(y, 2),因为前者只进行了一次乘法运算,避免了复杂的对数计算。 - Luis Colorado

4
您不能在C ++中使用'^'来实现这个目的。 而不是(x-center_x)^2+(y-center_y)^2 < radius^2 请使用(x - center_x) * (x - center_x) + (y - center_y) * (y - center_y) < radius * radius 。 坐标可以使用double类型,没有问题。

3
我认为这不是代码,而是原始问题中所使用的公式。 - NathanOliver
@NathanOliver,无论如何,SO规则建议发布完整的可测试代码,因此Shiro是正确的,假设OP正在尝试使用他发布的公式。 - Luis Colorado

4

这要看情况。

对于测试浮点值是否在阈值的一侧,通常最适合使用简单的有序不等式比较。

由于浮点误差,本应该在阈值一侧的结果可能会出现在另一侧。如果重要的是保证没有假阴性,即使增加了假阳性的几率,那么你提出的替代方案可能是合适的。

请注意,在输入值变化幅度很大时,基于常数epsilon的误差补偿并不有效。


4

不行。正如其他人所提到的,C中的运算符^是按位异或,而不是幂。但你可以使用内联函数:

inline double Sqr(double x) {return x*x;}
// ...
if (Sqr(x - center_x) + Sqr(y - center_y) < Sqr(radius)) // ...

关于你的问题,
fabs (Sqr(x - center_x) + Sqr(y - center_y) - Sqr(radius) ) < EPS

这句话的意思是(x,y)在圆的周长上。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接