我有这个简单的测试:
double h; ... // code that assigns h its initial value, used below ... if ((h>0) && (h<1)){ //branch 1 -some computations } else{ //branch 2- no computations }
我列出了我的值,因为我得到了一些非常奇怪的结果,例如:h = 1然后第一个分支到达,我不明白为什么因为如果h = 1我想要计算branch2.
我被一些如此明显的东西搞糊涂了吗?
这是我计算然后使用的方式h
:
double* QSweep::findIntersection(edge_t edge1,edge_t edge2) { point_t p1=myPoints_[edge1[0]]; point_t p2=myPoints_[edge1[1]]; point_t p3=myPoints_[edge2[0]]; point_t p4=myPoints_[edge2[1]]; double xD1,yD1,xD2,yD2,xD3,yD3,xP,yP,h,denom; double* pt=new double[3]; // calculate differences xD1=p2[0]-p1[0]; xD2=p4[0]-p3[0]; yD1=p2[1]-p1[1]; yD2=p4[1]-p3[1]; xD3=p1[0]-p3[0]; yD3=p1[1]-p3[1]; xP=-yD1; yP=xD1; denom=xD2*(-yD1)+yD2*xD1; if (denom==0) { return NULL; } else{ h=(xD3*(-yD1)+yD3*xD1)/denom; } std::cout<<"h is"<0)&&(h<1)){ pt[0]=p3[0]+xD2*h; pt[1]=p3[1]+yD2*h; pt[2]=0.00; } else{ return NULL; } } return pt;
}
好的,所以很明显我应该如何重新制定这个条件.
从:
double h; if (h==1){ //computations here }
至:
double h; if (abs(h-1)当我使用双数字.
但是我该如何重新制定这个呢?
double h; if (h<1){ //computations here }
Welbog.. 14
既然
h
是双倍的,它可能已经足够接近1来打印1
,但它实际上有点小于1所以比较成功.浮点数可以做很多事情.
1> Welbog..:既然
h
是双倍的,它可能已经足够接近1来打印1
,但它实际上有点小于1所以比较成功.浮点数可以做很多事情.
2> Bill the Liz..:通过最大精度打印来检查h的实际值.你可能会发现它实际上略低于1.0.
我运行以下代码作为测试
#includeint main() { double h = 1.0; if((h>0) && (h<1)) { std::cout << "first branch" << std::endl; } else { std::cout << "second branch" << std::endl; } } 输出是"第一个分支"(在Ubuntu 8.10上使用g ++ 4.3.2),但Indeera在评论中提到,在使用VS2005编译的Windows XP上运行的相同代码给出输出"第二个分支"(谢谢,Indeera).
您可以更改代码,将
h
0.0h
和1.0 之间的差异与某个小的delta值进行比较.double allowedDelta = 0.000001; if( ((h - 0.0) > allowedDelta) && ((1.0 - h) > allowedDelta) ) ... // h is between 0.000001 and 0.9999990请注意,在这种特殊情况下,"(h - 0.0)"可以替换为"h".我将其保留为具有说明价值的方式.
另请注意,如果您只进行一次比较,则需要将delta与h与某些常量之差的绝对值进行比较.由于你在这里检查一个范围,两个比较ANDed一起做了一个特殊情况,你可以绕过使用
abs
.如果h是负值或某个大于1.0的正值,则它将超出范围并且无法通过上述两个测试中的一个.