Archived

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

nazpyro

hm...explain anyone

Recommended Posts

here's a simple program:
#include <iostream.h>
#include <math.h>

int main()
{
	double btmTotal = 33.3 + 33.3 + 33.3 + 0.1;

	// Test 1
	if (btmTotal < 100)
		cout << "<";
	else if (btmTotal>100)
		cout << ">";
	else if (btmTotal == 100)
		cout << "==";

	cout << endl;

	// Test 2
	if (ceil(btmTotal) < 100)
		cout << "<";
	else if (ceil(btmTotal)>100)
		cout << ">";
	else if (ceil(btmTotal)==100)
		cout << "==";

	cout << endl;

	return 0;
}    
Test 1 has "<" printed, but Test 2 has "==" printed. Why? "Success is not the result of spontaneous combustion; you must set yourself on fire." Edited by - nazpyro on October 17, 2001 3:31:42 PM Edited by - nazpyro on October 17, 2001 3:32:02 PM Edited by - nazpyro on October 17, 2001 3:32:26 PM

Share this post


Link to post
Share on other sites
Here you''re dealing with the fact that floating point values are not exact. They are stored as binary numbers with limited precision, and as such are prone to rounding errors. A good site that explains IEEE floating point is:

http://www.math.grin.edu/~stone/courses/fundamentals/IEEE-reals.html

And I''m sure you could easily find more. The basic idea is that you store a floating point number as a binary number plus some binary exponent. Well, not every decimal number has an exact representation in this format; some sort of rounding is necessary. For example, in binary, the number .3 is represented as:

0.010011001...

And it keeps going for awhile. I''m pretty sure that there is no terminating number for .3 in binary. Anyway, you can see how some decimals have to be rounded off when converted to binary. The rounding errors don''t occur until after several decimal points, so they''re easy to miss. A way to get your program to show it to you is to set the precision of cout. Add the following lines to your program:

cout.setf(ios::fixed);
cout.precision(15);
cout << btmTotal << endl;

When this runs, you''ll see that btmTotal is not actually 100, but rather 99.999999999999986. As far as the computer is concerned, that is not equal to 100.

So what can you do about this? Well, you should rarely, if ever, check for equality against a floating point value. What I usually do is one of two things:

1. Round to the nearest integer (like you did in the ciel() part of your sample.) Integers are definite values in the computer, so they aren''t subject to rounding errors. However, this is not always a feasible choice.

2. When you want to check for equality, actually check for +/- some threshold. For example:
don''t do:
if(x==100)
but rather:
#define THRESHOLD .00000001
if(x>100-THRESHOLD&&x<100+THRESHOLD)

I''m not sure if this is the best way to do this; if someone has a better alternative, I''d be interested to hear it as well.

Share this post


Link to post
Share on other sites