From: "John M. Aldrich" Newsgroups: comp.os.msdos.djgpp Subject: Re: Floating point bug??? Date: Mon, 28 Apr 1997 10:49:37 +0000 Organization: Two pounds of chaos and a pinch of salt Lines: 66 Message-ID: <336480C1.37C2@SPAMcs.com> References: Reply-To: fighteer AT cs DOT com NNTP-Posting-Host: ppp103.cs.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk David Jenkins wrote: > > I'm having some trouble with comparing floats to integers. > The following source uses an integer target variable and a floating > point current variable. > I set the target to a random value the change the value of current > depending on whether it is lower or higher than the target variable. > > It seems simple a enough thing to ask my program to do. BUT it won't, > when it reaches "target" weird things happen. The "current" stays an > offset according to SPEED away from the "target". > I've even tried changing the "target" to a float. > Is there some function in C that I don't know about, I'm only a couple > of months old. ;-) Your problem is the cumulative error introduced by the lack of precision of floating point variables. If you change the print specifier to %.10f, you'll see this. By the time the value of current gets to the vicinity of 37, its actual value is 36.9000091553. Naturally, adding one to this makes the value higher than 37, so the second if statement is triggered and subtracts 0.1 from it. You get stuck in an infinite repetition because of the imprecision of floating point numbers. There's no easy way around the problem, because it even persists when you change the precision of current to double or long double. It's the repetitive additions and subtractions that cause the problem, not the comparison to an integer. You may want to try "pruning" the value by using something like this: current = floor( current * 100.0 + 0.5 ) / 100.0; Do this after each update to current and your program will work as intended (I just tested it myself). Some additional comments, though: - rand() is declared in - You should call srand() if you want to initialize the random number generator with a nonzero seed. Otherwise, you'll get exactly the same results every time you run your program. - random() is a much better RNG than rand(). Use srandom() to seed it. - A good seed is the clock value, obtained via time(). So the most commonly used way to seed the RNG is this: srandom( (int) time( 0 ) ); - Your if block within the loop is somewhat ambiguous. It might be better if you did it this way: if (current < target) current += SPEED; else if (current > target) current -= SPEED; else if (current == target) target = rand() % 100; That way, only one of the above items is performed at each pass through the loop. - If you want to delay your program, why not just use delay()? hth! -- John M. Aldrich, aka Fighteer I -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS d- s+:- a-->? c++>$ U@>++$ p>+ L>++ E>++ W++ N++ o+>++ K? w(---) O- M-- V? PS+ PE Y+ PGP- t+(-) 5- X- R+(++) tv+() b+++ DI++ D++ G>++ e(*)>++++ h!() !r !y+() ------END GEEK CODE BLOCK------