2

I had a program which requires one to search values from -100.00 to +100.00 with incrementation of 0.01 inside a for loop. But the if conditions arent working properly even if code is correct...

As an example I tried printing a small section i.e if(i==1.5){cout<<"yes...";} it was not working even though the code was attaining the value i=1.5, i verified that by printing each of the values too.

#include<iostream>
#include<stdio.h>

using namespace std;



int main()
{
    double i;

    for(i=-1.00; i<1.00; i=i+0.01)
    {
         if(i>-0.04 && i<0.04)
         {
             cout<<i;
             if(i==0.01)
                cout<<"->yes ";
             else
                cout<<"->no ";
         }
    }




    return 0;
}

Output:

-0.04->no -0.03->no -0.02->no -0.02->no -0.01->no 7.5287e-016->no 0.01->no 0.02->no 0.03->no

Process returned 0 (0x0) execution time : 1.391

(notice that 0.01 is being attained but still it prints 'no') (also notice that 0.04 is being printed even if it wasn't instructed to do so)

Alex Frost
  • 21
  • 1

2 Answers2

4

use this if(abs(i - 0.01) < 0.00000000001) instead.

double - double precision floating point type. Usually IEEE-754 64 bit floating point type

The crux of the problem is that numbers are represented in this format as a whole number times a power of two; rational numbers (such as 0.01, which is 1/100) whose denominator is not a power of two cannot be exactly represented.

In simple word, if the number can't be represented by a sum of 1/(2^n) you don't have the exact number you want to use. So to compare two double numbers calculate the absolute difference between them and use a tolerance value e.g. 0.00000000001 .

Oblivion
  • 7,176
  • 2
  • 14
  • 33
1

Doubles are stored in binary format. To cut things short fractional part is written as binary. Now let's imagine it's size is 1 bit. So you've two possible values (for fraction only): .0 and .5. With two bits you have: .0 .25 .5 .75. With three bits: .125 .25 .375 .5 .625 .75 .875. And so on. But you'll never get 0.1. So what computer does? It cheats. It lies to you, that 0.1 you see is 0.1. While it more looks like 0.1000000000000000002 or something like this. Why it looks like 0.1? Because formatting of floating point values has long standing tradition of rounding numbers, so 0.10000000000001 becomes 0.1. As a result 0.1 * 10 won't equal 1.0.

Correct solution is to avoid floating point numbers, unless you don't care for precision. If your program breaks, once your floating point value "changes" by miniscule amount, then you need to find another way. In your case using non-fractional values will be enough:

for(auto ii=-100; ii<100; ++ii)
{
     if(ii>-4 && ii<4)
     {            
         cout << (ii / 100.0);
         if(ii==1)
            cout<<"->yes ";
         else
            cout<<"->no ";
     }
}
Radosław Cybulski
  • 2,952
  • 10
  • 21