448,538 Members | 911 Online Need help? Post your question and get tips & solutions from a community of 448,538 IT Pros & Developers. It's quick & easy.

# Comparing floats

 P: n/a I have a function: int F(double a) { if (a = =1.0) { return 22; } return 44; } When I call F(1.0) it returns 22. But if I call F from a loop like: double a = 0.0; for (int j = 0; j <= 1000; j++) { std::cout << F(a) <
5 Replies

 P: n/a saneman writes: I have a function: int F(double a) { if (a = =1.0) { return 22; } return 44; } When I call F(1.0) it returns 22. But if I call F from a loop like: double a = 0.0; for (int j = 0; j <= 1000; j++) { std::cout << F(a) <

 P: n/a saneman wrote: I have a function: int F(double a) { if (a = =1.0) { return 22; } return 44; } When I call F(1.0) it returns 22. But if I call F from a loop like: double a = 0.0; for (int j = 0; j <= 1000; j++) { std::cout << F(a) < Do you need expertise in C++? I'm available. Aug 19 '08 #3

 P: n/a >This is because: >1) When internally represented in binary, fractional amounts areirrational.2) Addition accumulates roundoff errors.Add the following to your inner loop:std::cout << a << std::endl;You'll see what's happening. I have tried doing std::cout << a << std::endl; but it just prints the numbers from 0.001 to 1 as expected. Aug 19 '08 #4

 P: n/a saneman writes: >>This is because:1) When internally represented in binary, fractional amounts areirrational.2) Addition accumulates roundoff errors.Add the following to your inner loop:std::cout << a << std::endl;You'll see what's happening. I have tried doing std::cout << a << std::endl; but it just prints the numbers from 0.001 to 1 as expected. Probably the precision is not enough. Use std::setw and std::setprecision to increase the precision shown. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEABECAAYFAkiqqVwACgkQx9p3GYHlUOLihQCfdkVHJBzm5Q c5Dhu07NeXb6zh 2LQAn1M/jz6n9OX2okAqRvtJeQVDMGGo =vAtO -----END PGP SIGNATURE----- Aug 19 '08 #5

 P: n/a saneman wrote: After a few hours of messing with my brains I found a website where they say that comparing floats in C++ is not guranteed to return an expected result. There are a few flaws in that statement: - This is not related to C++ in particular, but computers in general. All programming languages which perform direct floating point comparisons will present the same issue. (Some programming languages might perform an automatic range comparison behind the scenes, but C++ only does exactly what you tell it to do, nothing more.) - Whether the result you are seeing is "expected" or not is a question of definition. For example, assume that I expect this comparison to return true: 0.3333333 + 0.3333333 + 0.3333333 == 1.0 but instead, it returns false. My expectation was wrong. In fact, the comparison returning false is what should be expected. Why? Because if you calculate that sum, you get 0.9999999, which is different from 1.0. Thus they should obviously compare unequal. In your example program you are summing 0.001 to itself. However, computers do not calculate with decimal numbers. They calculate with base-2 numbers with a limited amount of bits. Base-2 floating point values with a limited amount of bits cannot represent 0.001 accurately (for the exact same reason that decimal numbers cannot represent 1/3 accurately). Thus when you write 0.001, internally the actual value will be just a tiny bit smaller than that (exactly like 0.333333333333333 is a tiny bit smaller than 1/3). When you sum that with itself a thousand times, what you get is 1000 times that a-bit-smaller value, which ends up being a-bit-smaller than 1.0, which obviously compares unequal to 1.0. Thus summing 0.001 to itself 1000 times is *expected* to give a result which is smaller than 1.0 because 0.001 is actually a bit smaller than what it looks. (This doesn't mean that no decimal number can be represented accurately with base-2 floating point numbers. For example 1.0 and 0.5 can be represented accurately, without any rounding off.) The result of long calculations can accumulate these types of rounding errors, and thus the result may differ from what an infinitely-accurate mathematical formula would tell you. Thus you have to make ranged comparisons. Another option is to avoid floating point numbers altogether. In many situations they are just not needed. For example, if you just need all the values between 0.0 and 1.0, you can do this: for(int i = 0; i <= 1000; ++i) someFunctionTakingADouble(i/1000.0); Now, surprisingly, the last value given to the function will be exactly 1.0. Aug 19 '08 #6

### This discussion thread is closed

Replies have been disabled for this discussion. 