Archived

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

Seriously weird problem

This topic is 6361 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This is the weirdest bug I have ever had in a program. I have a function that creates a cone in my 3D app. One of the arguments I pass to the function is a level of detail value. This LOD value has to be between 0.0f and 1.0f. I multiply this value with 100 and I get the number of sides in the cone. The code looks like this:
        void BRUSH::CreateCone(float lod, float height, float width)
{
	logia.Log("{---Entered function BRUSH::CreateCone---}\n");

	//Variable to hold the number of sides in triangle

	int numsides;

	//Error checking

	if(lod <= 0.0f || lod > 1.0f)
		Error("The horizontal LOD value must be between 0.0f and 1.0f");

	if(height <= 0.0f)
		Error("Height can not be less than 1");

	if(width <= 0.0f)
		Error("Width can not be 0 or less than 0");
	//End of error checking


	//Set the current number of sides in this cone

	numsides = (int)(lod * 100.0f);
	logia.Log("The number of sides is %d", numsides);        
Do you see that Log row. It prints the number of sides to a file. If I pass the value 0.1f as the lod value then I can read that the number of sides is indeed 10 in the log file. If I pass 0.05f the log file says there are 5 sides in the cone. But here comes the weird part. If I pass 0.04f the file says 3 sides and if I enter 0.03 the log file says 2 sides. Does anyone have any idea what could be causing this. I have checked and rechecked that I really have passed 0.04f as the lod value. Please help. Edited by - Mr Cucumber on 7/15/00 2:21:25 AM

Share this post


Link to post
Share on other sites
Maybe, but I doubt it, you have a case where 0.04 * 100.0 = 3.99999999 and this rounds to 3. Floats will do this type of thing...

This should solve it...

numsides = (int) (lod * 100.5f);





Edited by - bishop_pass on July 15, 2000 5:37:04 AM

Share this post


Link to post
Share on other sites
Not maybe, definately!
The (int) cast on a float is very dangerous, because it will introduce bugs like that.
I had one that took about a week to find, where (int)(1.0f / 0.1f) = 9 .

Your best bet is to add (or subtract, depends on the direction of the operators and what you wish to achieve ) 0.5 onto the number, somewhat like you said, Bishop.

So this is a "rounding" operation:
    
numsides = (int)( lod * 100.0f + 0.5f );


In this case, Anything less than x.5 = x, and anything larger is x + 1;
This doesn''t work for negative numbers, so be careful.


Give me one more medicated peaceful moment.
~ (V)^|) |<é!t|-| ~
ERROR: Your beta-version of Life1.0 has expired. Please upgrade to the full version. All important social functions will be disabled from now on.

Share this post


Link to post
Share on other sites
quote:
Original post by Mr Cucumber
Thanks both of you.
I just can''t understand why it works for all other numbers.


It''s because most floating-point numbers CANNOT be represented exactly in binary. (This applies to other number bases as well, but since we''re talking computers here, let''s look at binary.)

For example, how can we represent one-half? 0.5 == 2^-1, and so it can be represented exactly.

But what about 0.75? It can also be exact: 0.75 == 0.5 + 0.25 == 2^-1 + 2^-2. It''s exact because it''s the sum of powers of 2 (the binary system).

Now try one-third... It can''t be done with any finite number of bits. (It can''t be done in decimal either, fwiw.)

So -- unlike integers which ARE exact within a limited range -- floating-points are usually not exact. You get rounding errors, and these can be exaggerated when converting to integers.

---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!

Share this post


Link to post
Share on other sites