floating point problems?

G

Gernot Frisch

Hi,

does repeatingly doing this:

float num = GetRandomFloat();
for(;;)
{
float random = GetRandomFloat();
num*=random;
num/=random;
}

Will num stay the same?
What can I do to make it stay the same (FixFloat(&random) e.g?)

--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

________________________________________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com
 
J

Jacek Dziedzic

Gernot said:
Hi,

does repeatingly doing this:

float num = GetRandomFloat();
for(;;)
{
float random = GetRandomFloat();
num*=random;
num/=random;
}

What about when num*random > maximum float?
Also, random == 0.0 gives you a floating division by zero.

And num will not stay the same because of precision losses.

- J.
 
G

Gernot Frisch

Jacek Dziedzic said:
What about when num*random > maximum float?
Also, random == 0.0 gives you a floating division by zero.

Taken care of that.
And num will not stay the same because of precision losses.

That's my question: Is there any way to make "random", so that
precision losses it not of any interest?
 
J

Jacek Dziedzic

Gernot said:
Taken care of that.




That's my question: Is there any way to make "random", so that
precision losses it not of any interest?

What I don't understand is why you insist on first multiplying
num by random, only to divide it by random a moment later? It's
not clear for me what you are trying to do. Do you simply want
to generate random float numbers within a certain range? It seems
not, because supposedly GetRandomFloat() does this for you.
So what are you trying to achieve?

- J.
 
J

John Harrison

Gernot Frisch said:
Taken care of that.


That's my question: Is there any way to make "random", so that precision
losses it not of any interest?

Yes

float num = GetRandomFloat();
for(;;)
{
float random = GetRandomFloat();
float save_num = num;
num*=random;
num = save_num;
}

Likely to be more efficient too, and clearer code.

john
 
K

Karl Heinz Buchegger

Gernot said:
Taken care of that.


That's my question: Is there any way to make "random", so that
precision losses it not of any interest?

If your question is: Is there a way to get the benefits
of floating point arithmetic while avoiding the precission loss
then the answer is: no.

The reason is simple: A genious once proved that there is an infinite
amount of rational numbers between 0 and 1. You can't represent an infinite
amount of numbers with a finite amount of bits.
So the problem with floating point numbers is system imanent and there is
nothing you can do about it. Live with it.
 
L

Lionel B

Gernot said:
Hi,

does repeatingly doing this:

float num = GetRandomFloat();
for(;;)
{
float random = GetRandomFloat();

num*=random;
num/=random;

What on earth is this supposed to achieve?
}

Will num stay the same?

No, because of loss of precision.
What can I do to make it stay the same (FixFloat(&random) e.g?)
Omit the lines:

num*=random;
num/=random;
 
K

Karl Heinz Buchegger

Gernot said:
Taken care of that.


That's my question: Is there any way to make "random", so that
precision losses it not of any interest?

Make it double instead of float?

Seriously: Until you know exactly what you do AND you know what
is awaiting you AND you are willing and have the knowledge to fight
that beast AND there is not a very, very, very good reason: forget
that data type float exists and use double instead.

The 'floating point problem' is still there with double, but it
is much smaller. Small enough that with a little bit of care it
can be ignored in practice (except for comparisons, of corse).
 
G

Gernot Frisch

float num = GetRandomFloat();
What on earth is this supposed to achieve?

float scale = GetScalingForCartoonOutlines();
for(int i=0; i<afewthousandtriangles; ++i)
{
ScaleVertex(pVertices, scale);
}
glDrawElements(pVertices, afewthousandtriangles);
scale=1.0f/scale;
for(int i=0; i<afewthousandtriangles; ++i)
{
ScaleVertex(pVertices, scale);
}

The other way would be to have an additional "afewthousandtriangles"
array of data that I don't really need.

Thx anyway,
-Gernot
 
K

Karl Heinz Buchegger

Gernot said:
What on earth is this supposed to achieve?

float scale = GetScalingForCartoonOutlines();
for(int i=0; i<afewthousandtriangles; ++i)
{
ScaleVertex(pVertices, scale);
}
glDrawElements(pVertices, afewthousandtriangles);
scale=1.0f/scale;
for(int i=0; i<afewthousandtriangles; ++i)
{
ScaleVertex(pVertices, scale);
}

The other way would be to have an additional "afewthousandtriangles"
array of data that I don't really need.


But you need it (see later).
It always a good idea to reserve memory for temporary results
if you then can avoid modifying the originals.

As for your specific problem. It is alwas a good idea
to know the toolkit you are working with.

glPushMatrix();
glScalef( 1.0 / scale, 1.0 / scale, 1.0 / scale );
glDrawElements( pVertices, afewthousandtriangles );
glPopMatrix();

Does the very same as your mumbo jumbo 2 loop solution.
 
K

Karl Heinz Buchegger

Karl said:
Gernot said:
float num = GetRandomFloat();
for(;;)
{
float random = GetRandomFloat();


num*=random;
num/=random;

What on earth is this supposed to achieve?

float scale = GetScalingForCartoonOutlines();
for(int i=0; i<afewthousandtriangles; ++i)
{
ScaleVertex(pVertices, scale);
}
glDrawElements(pVertices, afewthousandtriangles);
scale=1.0f/scale;
for(int i=0; i<afewthousandtriangles; ++i)
{
ScaleVertex(pVertices, scale);
}

The other way would be to have an additional "afewthousandtriangles"
array of data that I don't really need.


But you need it (see later).
It always a good idea to reserve memory for temporary results
if you then can avoid modifying the originals.

As for your specific problem. It is alwas a good idea
to know the toolkit you are working with.

glPushMatrix();
glScalef( 1.0 / scale, 1.0 / scale, 1.0 / scale );


Sorry, obviously must read:

glScalef( scale, scale, scale );
 
G

Gernot Frisch

glScalef( scale, scale, scale );

Unfortunately not, I've got to scale the vetices along their normal
directions, which makes this a bit expensive. I've decided to
implement a temp-buffer for each object now, thank you.
 
K

Karl Heinz Buchegger

Gernot said:
Unfortunately not, I've got to scale the vetices along their normal
directions, which makes this a bit expensive. I've decided to
implement a temp-buffer for each object now, thank you.

OK. If the center of scale is not identical for all points,
then thats the best solution.

That's one of the great principles in graphics:
Don't accumulate errors!

Eg. you want to rotate something in 0.1 degree steps for
a full circle:

Don't do

for( double alpha = 0; alpha < 360.0; alpha += 0.1 ) {
// apply the angle

But do:

for( int i = 0; i < 3600; ++i )
alpha = i * 0.1;

So why is the second better?
Because in the first loop, the error of the first addition
will be distibuted to the second addition which in turn will
influence the 3-rd addition etc. All in all you are doing 3600
additions and in the end you will have accumulated a lot of error.

"Working with floating point numbers is like moving piles of sand.
Every time you do it, you loose a little sand and pick up a little
dirt"
 
A

Arijit

Karl said:
OK. If the center of scale is not identical for all points,
then thats the best solution.

Center of scale ? You mean the origin of the coordinate system, right ?
The origin has no relation to the normal vectors, because the do not
change under translation. The problem I believe is that if you scale
normal vectors, you enable Normalization, which is expensive.

-Arijit
 
J

Jacek Dziedzic

Karl said:
"Working with floating point numbers is like moving piles of sand.
Every time you do it, you loose a little sand and pick up a little
dirt"

Now, that's a nice proverb! :)

- J.
 
G

Gernot Frisch

Center of scale ? You mean the origin of the coordinate system,
right ? The origin has no relation to the normal vectors, because
the do not change under translation. The problem I believe is that
if you scale normal vectors, you enable Normalization, which is
expensive.

Nah. Thin of a donut. When you scale it, the inner rings will go
further from the center, right? Now scale each vertex point along it's
normal direction. You get a blown-up donut this way.
 
K

Karl Heinz Buchegger

Arijit said:
Center of scale ? You mean the origin of the coordinate system, right ?

No. I mean 'center of scale'. The point that should be invariant under
the scale operation.
The origin has no relation to the normal vectors, because the do not
change under translation. The problem I believe is that if you scale
normal vectors, you enable Normalization, which is expensive.

I don't think that the OP has that problem.
 
K

Karl Heinz Buchegger

Gernot said:
Nah. Thin of a donut. When you scale it, the inner rings will go
further from the center, right? Now scale each vertex point along it's
normal direction. You get a blown-up donut this way.

I see. You are right. That cannot be done with a classical scale
operation. The classical scale operation assumes that the center
of scale is a single point, which it isn't in your case.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,815
Latest member
treekmostly22

Latest Threads

Top