Archived

This topic is now archived and is closed to further replies.

HellRaiZer

Strange floating point things!!!!!!

Recommended Posts

A few days ago, while i was debugging a piece of code, i realized something. NEVER TRUST FLOATs!!! ONLY INTs AND DOUBLEs!!! Let me explain this a bit. This is very strange, and i want an explanation, if possible!!! For some strange reason, i wanted to find all coplanar adjacent polygons, for a specific model, and group them in sets. So my test function, was something like this... 1 bool PolySet::CheckIfTriangleFits(Triangle* tri) 2 { 3 int i,j, numTrisInSet = TriList.size(); 4 Triangle* curTriangle = NULL; 5 for(i = 0;i; 8 for(j=0;j<3;j++) 9 { 10 if(curTriangle->Neighbour[j] == tri) 11 { 12 if(curTriangle->Plane.DistanceFromOrigin != tri->Plane.DistanceFromOrigin) 13 continue; 14 if(curTriangle->Plane.Normal != tri->Plane.Normal) 15 continue; 16 return true; 17 } 18 } 19 } 20 } While i was debugging this function, i saw some strange things... I''m using Microsoft Visual C++ v6.0 (VS98). DistanceFromOrigin is a float and Normal is a Vector3f. The next-instruction pointer was at line 12. The watch window showed this values: curTriangle->Plane.DistanceFromOrigin = -5.40000 tri->Plane.DistanceFromOrigin = -5.40000 Guess what happened when i pressed F10... If you thought that the next-instruction pointer pointed to line 14 (the normal to normal check) you are wrong!!!! For some strange reason, despite the fact that the two values were equal, the boolean expression at line 12 was true!!!!! The same happened for another polygon, at line 14. Despite the fact that the two normals were equal, the if-statement was true!!! Can anyone explain this to me????? The problem solved when i changed line 12 to this: 12 if(fabs(curTriangle->Plane.DistanceFromOrigin - tri->Plane.DistanceFromOrigin) <= EPSILON) 13 continue; where EPSILON was a very small value. HellRaiZer

Share this post


Link to post
Share on other sites
Yes. Floats are inaccurate. The chances are that you were actually comparing -5.4000000 with -5.4000001, but they appear the same due to the way they are represented inside the FPU.

By and large, you shouldn''t directly compare floats for equality, and the same goes for doubles.

Share this post


Link to post
Share on other sites
That''s a common problem with floats. Values to the right of the decimal point sometimes need to be rounded during conversions between oct (what''s in memory) and decimal (what you see).


  
float a = 5.5;
float b = 5.0;
b += 0.2;
b += 0.2001;
b += 0.0999;
cout << "a = " << a << ", b = " << b << "\n";
if (a == b) {
cout << "No guarantee this will be true.\n";
}


Here, even though the values may appear the same when represented in decimal, the values in memory may not be exactly the same.

Your solution is probably as good as any.

Share this post


Link to post
Share on other sites