Can't understand this... (logic problem?)

On my prog class we had this problem:
user 1 have 1.10 height
user 2 have 1.40 height
user 1 have 0.30 grow rate per year
user 2 have 0.15 grow rate per year

How many years will take for user1 to grow taller than user2?

It should be 3 years right, but i'm getting this.

If i use this code i get 2 years:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 int main()
{
    int year = 0;
    float user1 = 1.10;
    float user2 = 1.40;
    float i = 0.15;
    float x = 0.30;

   while (user1 <= user2)
     {
        user1 = user1 + x;
        user2 = user2 + i;
        year++;
        cout << "User1 have " << user1 << "m " << endl;
        cout << "User2 have " << user2 << "m" << endl;
    }

    cout << "\nUser1 took " << year << " to grow taller than user2." << endl << endl;


    return 0;
}


If i use this code i get 3 years.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main()
{
    int year = 0;
    float user1 = 1.10;
    float user2 = 1.40;
    //float i = 0.15;
    //float x = 0.30;

   while (user1 <= user2)
     {
        user1 = user1 + 0.30;
        user2 = user2 + 0.15;
        year++;
        cout << "User1 have " << user1 << "m " << endl;
        cout << "User2 have " << user2 << "m" << endl;
    }

    cout << "\nUser1 took " << year << " to grow taller than user2." << endl << endl;


    return 0;
}


They should have same result right? I can't understand why the different results.
Can someone enlighten me :) thx.
It's because floating point values are not very precise. They are more like approximations. Not all floating point values can be stored exactly and calculations will have rounding errors.
hmm, i get it.
How do i do "precise" calculation with decimal values then?
another type of variable?

thx
The two versions are not identical because of the mix of types float and double.

You can make them the same by specifying the literals to be of type float.

0.30 and 0.15 are interpreted as doubles, thus the addition is carried out by making both values into doubles, before storing the result.
1
2
        user1 = user1 + 0.30; 
        user2 = user2 + 0.15;


0.30f and 0.15f are now specified as float, thus the addition is carried out with both values of type float.
1
2
        user1 = user1 + 0.30f;
        user2 = user2 + 0.15f;
Do you really need them to be precise?

To calculate the number of years you don't need to use a loop. You could use simple algebra and that would give you an answer that is very close to the correct answer (2).

user1 = 1.10 + year * 0.30
user2 = 1.40 + year * 0.15

user1 = user2
1.10 + year * 0.30 = 1.40 + year * 0.15
year * (0.30 - 0.15) = 1.40 - 1.10
year = (1.40 - 1.10) / (0.30 - 0.15)
year = 0.30 / 0.15
year = 2
Illustration of the inaccuracy using different types:
The third version uses type double throughout.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
#include <fstream>
#include <iomanip>

    using namespace std;
    
void f1();
void f2();    
void f3();    

int main()
{
    cout << fixed << setprecision(7);
    f1();
    f2();
    cout << fixed << setprecision(16);
    f3();

    return 0;
}

void f1()
{
    cout << "\n---------------- f1 ---------\n";    
    int year = 0;
    float user1 = 1.10;
    float user2 = 1.40;
    float i = 0.15;
    float x = 0.30;

    while (user1 <= user2)
    {
        user1 = user1 + x;
        user2 = user2 + i;
        year++;
        cout << "User1 have " << user1 << "m " << endl;
        cout << "User2 have " << user2 << "m" << endl;
    }

    cout << "\nUser1 took " << year << " to grow taller than user2." << endl << endl;    
}

void f2()
{
    cout << "\n---------------- f2 ---------\n";    
    int year = 0;
    float user1 = 1.10;
    float user2 = 1.40;
    //float i = 0.15;
    //float x = 0.30;

    while (user1 <= user2)
    {
        user1 = user1 + 0.30;
        user2 = user2 + 0.15;
        year++;
        cout << "User1 have " << user1 << "m " << endl;
        cout << "User2 have " << user2 << "m" << endl;
    }

    cout << "\nUser1 took " << year << " to grow taller than user2." << endl << endl;
}

void f3()
{
    cout << "\n---------------- f3 ---------\n";
    int year = 0;
    double user1 = 1.10;
    double user2 = 1.40;
    double i = 0.15;
    double x = 0.30;

    while (user1 <= user2)
    {
        user1 = user1 + x;
        user2 = user2 + i;
        year++;
        cout << "User1 have " << user1 << "m " << endl;
        cout << "User2 have " << user2 << "m" << endl;
    }

    cout << "\nUser1 took " << year << " to grow taller than user2." << endl << endl;
    
}


---------------- f1 ---------
User1 have 1.4000001m
User2 have 1.5500000m
User1 have 1.7000000m
User2 have 1.6999999m

User1 took 2 to grow taller than user2.


---------------- f2 ---------
User1 have 1.4000000m
User2 have 1.5500000m
User1 have 1.6999999m
User2 have 1.6999999m
User1 have 1.9999999m
User2 have 1.8499999m

User1 took 3 to grow taller than user2.


---------------- f3 ---------
User1 have 1.4000000000000001m
User2 have 1.5499999999999998m
User1 have 1.7000000000000002m
User2 have 1.6999999999999997m

User1 took 2 to grow taller than user2.


Not really.
that was an exercise and i just got troubled by the diff results on what i thought was almost the same code, 1 using float variable 1 using direct value on calculation. (btw double type worked).

Just asked if there are a "precise" way, just to learn :)
If in any point i need to do some decimal operation with variables.
what should i use? double? function?

thx for all the clarifications and tips.
Generally type double is to be preferred.

However the difficulty comes in testing whether or not two floating point values are equal. In some situations you may subtract one from the other and check whether the absolute (no sign) difference is less than a certain amount.
Thnx, Chervil and Peter87. You helped me a lot to understand floating point.
:)
Topic archived. No new replies allowed.