处理0.0和-0.0,如何正确比较值
Dealing with 0.0 and -0.0, how to properly compare values
我正在研究函数来确定圆和射线是否相互相交。该功能的基础来自于本网站具体的这个页面。在第一页的注释中,作者讨论了圆和射线的相交,他列出了确定圆和射线是否相交的方法
确切的行为由正方形内的表达式决定根b * b - 4 * a * c
如果该值小于0,则该行不存在
如果它等于0,则该线与球体相交
如果它大于0,则直线与球体相交于两点。
这就是我代码中的问题所在。这就是下面函数中double bb4ac
的比较。
bool CircleRayIntersect(double ip1_x, double ip1_y, double ip2_x, double ip2_y,
double isc_x, double isc_y, double isc_r,
double &out1_x, double &out1_y,
double &out2_x, double &out2_y)
{
double a,b,c;
double bb4ac;
double r = isc_r;
double dp_x;
double dp_y;
double mu_1;
double mu_2;
double p1_x = ip1_x;
double p1_y = ip1_y;
double p2_x = ip2_x;
double p2_y = ip2_y;
double sc_x = isc_x;
double sc_y = isc_y;
dp_x = p2_x - p1_x;
dp_y = p2_y - p1_y;
a = dp_x * dp_x + dp_y * dp_y;
b = 2 * (dp_x * (p1_x - sc_x) + dp_y * (p1_y - sc_y));
c = sc_x * sc_x + sc_y * sc_y ;
c += p1_x * p1_x + p1_y * p1_y;
c -= 2 * (sc_x * p1_x + sc_y * p1_y);
c -= r * r;
bb4ac = b * b - 4 * a * c;
// Checks to make sure that the line actually intersects
TRACE(" -- Checking a: %fn", a);
TRACE(" -- Checking bb4ac: %fn", bb4ac);
if (abs(a) < 1E-9 || bb4ac < 0.0)
{
if(bb4ac < 0.0)
{
TRACE("bb4ac is less than zero: %d < 0.0 = %dn", bb4ac, (bb4ac < 0.0));
TRACE("bb4ac is less than zero: %f < 0.0 = %fn", bb4ac, (bb4ac < 0.0));
}
if (abs(a) < 1E-9)
TRACE("abs(a) is less than zeron");
mu_1 = 0;
mu_2 = 0;
TRACE("Ray does not intersect with circle!n");
return FALSE;
}
mu_1 = (-b + sqrt(bb4ac)) / (2 * a);
mu_2 = (-b - sqrt(bb4ac)) / (2 * a);
out1_x = p1_x + (mu_1*(p2_x-p1_x));
out1_y = p1_y + (mu_1*(p2_y-p1_y));
out2_x = p1_x + (mu_2*(p2_x-p1_x));
out2_y = p1_y + (mu_2*(p2_y-p1_y));
return TRUE;
}
在某些情况下,当使用某些参数调用此代码时,bb4ac
最终等于-0.0
。当这种情况发生时,根据上面列出的规则检查bb4ac
就会失效。以下是bb4ac
为-0.0
时TRACE
语句的一些示例输出。
-- Checking a: 129.066667
-- Checking bb4ac: -0.000000
bb4ac is less than zero: 0 < 0.0 = -1114636288
bb4ac is less than zero: -0.000000 < 0.0 = 0.000000
从TRACE
的输出来判断,看起来比较bb4ac
和0
的if(..)
语句没有正确地解释bb4ac
。看到bb4ac
在用%d
标志解释时被打印为-1114636288
,用%f
标志解释时被打印为-0.000
,我不得不认为bb4ac
在if
语句中被解释为-1114636288
,而不是-0.000
。
我怎样才能写if语句来正确地解释bb4ac
作为-0.000
?为什么它一开始会这么看呢?
假设TRACE
是一个类似printf
的varargs函数,使用%d
和double
参数,或%f
和int
或bool
参数是未定义的行为。使用正确的格式说明符或将参数强制转换为正确的类型。
您似乎很熟悉这样一个事实,即双比较永远不应该是精确的(即:你应该宽容,但你做得不太对。检查一个数字是否小于零:
if (x < -1E-9)
检查一个数字是否大于零:
if (x > 1E-9)
检查一个数字是否为零:
if (x > -1E-9 && x < 1E-9)
相关文章:
- 不正确的比较和交换计数器输出用于快速排序功能
- 将三角函数的正确值与matlab进行比较
- 通过比较 GetCurrentProcessId();获得正确的 HWND
- 如何正确比较整数和浮点值
- C++,"由于数据类型范围有限,比较总是正确的"
- C++中的结构是否按顺序分配内存?每次都以某种方式获得指针比较的正确答案
- 简单的程序比较阵列运行但给出不正确的结果
- 自定义迭代器:如果 a 和 b 的行为不同,如何正确处理距离计算和相等比较
- 无符号int的比较始终是正确的(NPOS问题?)
- "正确"无符号整数比较
- 如何正确比较存储在内存中的两个数组?
- 正确的方法或设计模式,以简化类中的“operatorX”函数,以按给定顺序比较相同类型的属性
- 为什么在浮点比较中,最后一个小数位数为5的浮点值能给出正确的输出,而在其他情况下却不是
- 优先队列未正确比较C
- 使用具有整数表示和 ULP 的混叠正确比较双精度
- 如何正确比较字符和0x85
- strcmp() 未正确比较字符串的问题
- 处理0.0和-0.0,如何正确比较值
- 如何正确比较两个无符号字符?
- 不能正确比较两个数字