PDA

View Full Version : fp bugs may screw GL rendereing?

Hull
03-17-2001, 11:29 PM
Hi. I know this might be abit off focus, but I just got to ask.

Observe the following code snip:

static double step = 0.0;
static double gldb = 0.0;
static double gldb2 = 7.0;
static int gli = 0;
static int bits = 0;

cout << "Fp bug. Test 1." << endl;
cout << endl;

cout << "Variables used:" << endl;
cout << "double's" << endl;
cout << " step=0.0, gldb=0.0, gldb2=7.0" << endl;
cout << "int's" << endl;
cout << " gli=0, bits=0" << endl;
cout << endl;

cout << "Operation: step = 1.0/12.0;" << endl;
step = 1.0/12.0;
cout << "step is now: " << step << endl;
cout << "d7step12 = 7*step*12 = " << 7*step*12 << endl;
cout << "d12step7 = 12*step*7 = " << 12*step*7 << endl;

static double d7step12,d12step7;

d7step12 = 7*step*12;
d12step7 = 12*step*7;

cout << "Operation: bits = memcmp(&(d7step12),&(d12step7),sizeof(double)); " << endl;
bits = memcmp(&(d7step12),&(d12step7),sizeof(double));

if(bits < 0)
{
cout << " d7step12 is bitwise SMALLER than d12step7." << endl;
}
else if(bits > 0)
{
cout << " d7step12 is bitwise BIGGER than d12step7." << endl;
}
else
{
cout << " d7step12 is bitwise EQUAL to d12step7." << endl;
}

cout << endl;

cout << "Operation: gldb = 7*step*12" << endl;
//gldb = 7*12*step; // works...
//gldb = 12*step*7; // works...
//gldb = 7*step*12; // Does NOT work.
gldb = step*7*12; // Does NOT work.

cout << "gli is now: " << gli << endl;
cout << "gldb is now: " << gldb << endl;
cout << "gldb2 is now:" << gldb2 << endl;
cout << endl;

//cout << "Now the funny part..." << endl;
cout << "Operation: gli = gldb" << endl;

gli = gldb;

cout << "gli is now: " << gli << endl;
cout << "gldb is now: " << gldb << endl;
cout << "gldb2 is now:" << gldb2 << endl;

cout << "comparing gldb and gldb2 bitvalues:" << endl;

cout << "Operation: bits = memcmp(&gldb,&gldb2,sizeof(double));" << endl;

bits = memcmp(&gldb,&gldb2,sizeof(double));

if(bits < 0)
{
cout << " gldb is bitwise SMALLER than gldb2." << endl;
}
else if(bits > 0)
{
cout << " gldb is bitwise BIGGER than gldb2." << endl;
}
else
{
cout << " gldb is bitwise EQUAL to gldb2." << endl;
}

cout << endl;

Now WHY does my comp say that:

d7step12 is equal in value to d12step7, namely 7.0
but they actually differ in a bitwise compare ?

And why do the value of gldb. which here is step*7*12 = 7
convert to 6 when doing the operation gli = gldb, whereas
gli is an int and gldb is a double? http://www.opengl.org/discussion_boards/ubb/redface.gif

These errors in floating point values where found doing recursive hiearchial
terrain expansion using fractal brownian motion. And its very ANNOYING http://www.opengl.org/discussion_boards/ubb/tongue.gif to get
incontinous functions where there should be continous values, punching big holes
in the generated terrain (ok, glitches).

For OpenGL implementations, do hardware manufactures take these possible fp bugs
in account making their drivers, or is there actually some potential arithmetic
problems in OpenGL that will surface in applications using alot of fp arithmetic?

Is it my machine or compiler?

Pentium 2/233mhz MMX
Riva TNT2
VC++ 6.0

Any clues to these fp bugs, or do we all have to revert to integer based arithmetic
to get some correct results in the end?

/Hull

Bob
03-18-2001, 04:45 AM
This is no bug, it's proper behaviour of the floatingpoint numbers.

A float does not have infinite precision, and almost always you get roundoff errors to some degree. A simple number as 10.0 cannot be represented exactly, only more or less close to 10.0, depending on precision, but NEVER exactly 10.0.

>>d7step12 is equal in value to d12step7, namely 7.0 but they actually differ in a bitwise compare ?

First you multiply with 12, then step and finaly 7. None of these three number is exact, only approximations. And when multiplying the other way aroung, 7*step*12, you get different amounts of errors, but then final result is, when printed on the screen, close enough eachother to be treated as the same number, but bitwise then are still not equal.

>>And why do the value of gldb. which here is step*7*12 = 7 convert to 6 when doing the operation gli = gldb, whereas gli is an int and gldb is a double?

Same goes here, roundoff error. You assign the value 1/12 to step, and when multiplied with 7*12, you excpect to get 7. This is not the case, because you don't assign 1/12 to step, only an approximation of 1/12. Nor do you multiply with 7 and 12, but approximations of these two numbers.
The final result might be close to 6.9999999, whic is treated as 7 when printed, but when converting to an integer, only the integerpart is taken, therefore 6.

NEVER assume anything when using floatingpoint maths.

Hull
03-18-2001, 07:22 AM
Ok, thanx for clarifying this to me.

http://www.opengl.org/discussion_boards/ubb/smile.gif