Archived

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

DirectXXX

unexpected float t=0.0f to t=1.0f FOR LOOP

Recommended Posts

I just recently noted it. for (float t=0.0f; t<=1.0f; t+=0.1f) this was supposed to end at 1.0f but it doesnt. it ends at 0.9f Also it works when im using double instead of float. What is the reason.??

Share this post


Link to post
Share on other sites
because you should never be checking for equality between floating point numbers, because of precision errors.

Try this:

for (float t=0.0f; t<=1.0f + epsilon; t+=0.1f)

where epsilon is 1e-5 or so.


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites
The FPU is not accurate.

For example 123456789 is converted to 1234567936 with 32 bit floats. Epsilon is a value that defines a range in which two numbers are treated as equal.

[edited by - novum on July 3, 2003 5:34:20 PM]

Share this post


Link to post
Share on other sites
*shrug* okay.

It helps to know a little bit about how floating point numbers are stored. Basically, they store an exponent and a mantissa (and a sign-bit), like scientific notation, except with base-2. So numbers that are not powers of two are only represented approximately. When those numbers are printed, they usually come out close enough to be rounded to the intended number, but compounded error (such as would be produced by successively adding to a number) can result in numbers like 1.000000000123, which is something like what the last value in your for-loop was.


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites
Or you can do:

for (float t = 0.0f; t < 1.1f; t+=0.1f)

Treating the float the way you probably would an int...

______________________________________________________________
The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ
MySite
______________________________________________________________

Share this post


Link to post
Share on other sites
quote:
Original post by Thunder_Hawk
Or you can do:

for (float t = 0.0f; t < 1.1f; t+=0.1f)

Treating the float the way you probably would an int...

Bad idea. Floating point error can go both ways; it''s entirely possible to end up with 1.09999999997 making the loop do another iteration.


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites
quote:
Original post by Fredrik Dahlberg
loop on ints!

#define DELTA_T 0.1

float t=0.0f;

for(int i=0; i<10; i++)
{
do stuff with t;
t += DELTA_T;
}

At least this is the "right" solution


Why not just go:

for (int i = 0; i < 11; i++) {
float t = 0.1f*i;
}

and do away with cumulative error all together


______________________________________________________________
The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ
MySite
______________________________________________________________

Share this post


Link to post
Share on other sites
quote:
Original post by Sneftel
Bad idea. Floating point error can go both ways; it''s entirely possible to end up with 1.09999999997 making the loop do another iteration.


Whoops I knew that

______________________________________________________________
The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ
MySite
______________________________________________________________

Share this post


Link to post
Share on other sites
quote:
Original post by Thunder_Hawk
quote:
Original post by Fredrik Dahlberg
loop on ints!

#define DELTA_T 0.1

float t=0.0f;

for(int i=0; i<10; i++)
{
do stuff with t;
t += DELTA_T;
}

At least this is the "right" solution


Why not just go:

for (int i = 0; i < 11; i++) {
float t = 0.1f*i;
}

and do away with cumulative error all together


______________________________________________________________
The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ
MySite
______________________________________________________________



..and also do the intToFloat thing the computer just love?

Share this post


Link to post
Share on other sites
Hm it''s the Intel architecture that doesn''t like integer to floating point conversions, because the C standard says the number has to be truncated, but fild rounds the number, so every integer/float conversion takes more than 20 instructions O_o

Share this post


Link to post
Share on other sites