mad*_*ina 4 c++ floating-point
我有这个简单的测试:
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
}
Run Code Online (Sandbox Code Playgroud)
我列出了我的值,因为我得到了一些非常奇怪的结果,例如: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"<<h<<endl;
if (h < 1) std::cout<<"no"<<endl;
else std::cout<<"yes"<<endl;
if (h==1) {
return NULL;
}
else{
if ((h>0)&&(h<1)){
pt[0]=p3[0]+xD2*h;
pt[1]=p3[1]+yD2*h;
pt[2]=0.00;
}
else{
return NULL;
}
}
return pt;
Run Code Online (Sandbox Code Playgroud)
}
好的,所以很明显我应该如何重新制定这个条件.
从:
double h;
if (h==1){
//computations here
}
Run Code Online (Sandbox Code Playgroud)
至:
double h;
if (abs(h-1)<tolerance){
//computations here
}
Run Code Online (Sandbox Code Playgroud)
当我使用双数字.
但是我该如何重新制定这个呢?
double h;
if (h<1){
//computations here
}
Run Code Online (Sandbox Code Playgroud)
通过最大精度打印来检查h的实际值.你可能会发现它实际上略低于1.0.
我运行以下代码作为测试
#include <iostream>
int main()
{
double h = 1.0;
if((h>0) && (h<1))
{
std::cout << "first branch" << std::endl;
}
else
{
std::cout << "second branch" << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
输出是"第一个分支"(在Ubuntu 8.10上使用g ++ 4.3.2),但Indeera在评论中提到,在使用VS2005编译的Windows XP上运行的相同代码给出输出"第二个分支"(谢谢,Indeera).
您可以更改代码,将h0.0 h和1.0 之间的差异与某个小的delta值进行比较.
double allowedDelta = 0.000001;
if( ((h - 0.0) > allowedDelta) && ((1.0 - h) > allowedDelta) )
... // h is between 0.000001 and 0.9999990
Run Code Online (Sandbox Code Playgroud)
请注意,在这种特殊情况下,"(h - 0.0)"可以替换为"h".我将其保留为具有说明价值的方式.
另请注意,如果您只进行一次比较,则需要将delta与h与某些常量之差的绝对值进行比较.由于你在这里检查一个范围,两个比较ANDed一起做了一个特殊情况,你可以绕过使用abs.如果h是负值或某个大于1.0的正值,则它将超出范围并且无法通过上述两个测试中的一个.