Search code examples
c++double

C++ double wierd behaviour during incrementing in for loop


I was making a progress bar when I noticed this, Something wierd is happening when incrementing doubles in for loop.

EDIT : I am not asking why floating points are broken !! My issue is that the for loop is iterating one extra time in case 1 and one less time in case 4 !

I have created 4 test cases. Please See the code below :-

#include <iostream>

using namespace std;
 
int main()
{
    cout << endl << "Should End on 0.9 :-" << endl; // Abnormal
    for (double i = 0 ; i < 1 ; i += 0.1) cout << i << endl;
    
    cout << endl << "Should End on 1 :-" << endl;
    for (double i = 0 ; i <= 1 ; i += 0.1) cout << i << endl;
    
    cout << endl << "Should End on 0.99 :-" << endl;
    for (double i = 0 ; i < 1 ; i += 0.01) cout << i << endl;
    
    cout << endl << "Should End on 1 :-" << endl;   // Abnormal
    for (double i = 0 ; i <= 1 ; i += 0.01) cout << i << endl;
}

Output :-

Should End on 0.9 :-
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1

Should End on 1 :-
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1

Should End on 0.99 :-
0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1
0.11
0.12
0.13
0.14
0.15
0.16
0.17
0.18
0.19
0.2
0.21
0.22
0.23
0.24
0.25
0.26
0.27
0.28
0.29
0.3
0.31
0.32
0.33
0.34
0.35
0.36
0.37
0.38
0.39
0.4
0.41
0.42
0.43
0.44
0.45
0.46
0.47
0.48
0.49
0.5
0.51
0.52
0.53
0.54
0.55
0.56
0.57
0.58
0.59
0.6
0.61
0.62
0.63
0.64
0.65
0.66
0.67
0.68
0.69
0.7
0.71
0.72
0.73
0.74
0.75
0.76
0.77
0.78
0.79
0.8
0.81
0.82
0.83
0.84
0.85
0.86
0.87
0.88
0.89
0.9
0.91
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99

Should End on 1 :-
0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1
0.11
0.12
0.13
0.14
0.15
0.16
0.17
0.18
0.19
0.2
0.21
0.22
0.23
0.24
0.25
0.26
0.27
0.28
0.29
0.3
0.31
0.32
0.33
0.34
0.35
0.36
0.37
0.38
0.39
0.4
0.41
0.42
0.43
0.44
0.45
0.46
0.47
0.48
0.49
0.5
0.51
0.52
0.53
0.54
0.55
0.56
0.57
0.58
0.59
0.6
0.61
0.62
0.63
0.64
0.65
0.66
0.67
0.68
0.69
0.7
0.71
0.72
0.73
0.74
0.75
0.76
0.77
0.78
0.79
0.8
0.81
0.82
0.83
0.84
0.85
0.86
0.87
0.88
0.89
0.9
0.91
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99

[Program finished]

First case should end on 0.9 but it's ending on 1

And 4th case should end on 1 but it's ending on 0.99

2nd and 3rd case are working normally.

Any ideas what's going on here ? What am I doing wrong ?

I am using Clang compiler on aarch64 cpu.


Solution

  • The answer is that floating points are "broken" - or at least not trusted for exact values.

    In loop 1, when it unexpectedly prints 1.0, the actual value is slightly less (0.999...), so the check that it is less than 1 is still true.

    In loop 4, when you expect it to print 1.0, the actual value is slightly higher (1.0001 or something), so the check that it is <= 1 fails.