Why aren't the doubles enabling their 14 point precision?

Write your question here.
So, the purpose of my code is to not only print which numbers are bigger or smaller but also print whether or not they are ALMOST equal. ALMOST equal is defined by whether or not the difference between them is 1.0/10000000.

So, when i input 21.9999999 && 21.9999998 Both numbers just seem to jump to 22, and that is not sexy.

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
  #include <vector>
#include <iostream>
#include <string>
#include <stdio.h>
#include <algorithm>

using namespace::std; 


int main(){
double a;
double b;
double temp;

cout << "Please enter an double.";

while(cin >> a >> b)

if (a > b){
cout << "The larger value is a:" << a << "\n The smaller value is b:" << b << endl; 
if((a-b)== (1.0/10000000)){
cout << "The numbers are almost equal.";
}
} 

else if (b > a){
cout << "the larger value is b: " << b << "\n The smaller value is a:" << a << endl;
if((b-a)==(1.0/10000000)){
cout << "The numbers are almost equal.";
}
}

else if (a == b){
cout << "The two numbers are equal." << endl;
}
}
A double CANNOT exactly represent the number 21.9999999
A double CANNOT exactly represent the number 21.9999998

Here's a page showing what a 32 bit long floating point number can do; try entering those two numbers here.

https://www.h-schmidt.net/FloatConverter/IEEE754.html

That webpage will show you the closest value that a 32 bit float can manage. Will show you what the actual stored number is. The same principle applies to a 64 bit floating point number, if that's what you're using as a double.

Read about floating point here: https://floating-point-gui.de/

The key fact to remember is that floating point numbers CANNOT represent every decimal value. They can only represent some of them. A very small amount of them.
Last edited on
the decimal part of a real is still binary so column values are 2^-n

therefore half/quarter/eighth/sixteenth etc and all combinations of them should work perfectly.
(0.5 / 0.25 / 0.125 / 0.0625) all perfectly representable with 2^-n columns.

as Repeater says, that's quite a small subset that a real can actually hold with any accuracy.

this is why most folk say never test reals for equality, (fX == fY) just isn't trustworthy.
results of multiplications and divisions make an exact answer almost unpredictable.


You can approximate by checking whether the difference is less than or equal to your epsilon (or maybe it's just less than, not quite sure). Measuring equality between floating point numbers is hard. This may be approx what you want, and in order to "see" that precision in the console, set it:

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
#include <iostream>
#include <iomanip>

using namespace std; 

int main()
{
    double a;
    double b;
    double temp;
    cout << setprecision(12);
    double epsilon = 1.0/10000000;

    cout << "Please enter two space-separated doubles (-1 -1 to stop):\n";
    while(cin >> a >> b)
    {
        if (a == -1 && b == -1)
            break;
               
        if (a > b)
        {
            cout << "The larger value is a: " << a <<
                    "\nThe smaller value is b: " << b << endl;
            if ( a-b <= epsilon ) 
                cout << "The numbers are almost equal.\n";            
        }
        else if (b > a)
        {
            cout << "The larger value is b: " << b <<
                    "\nThe smaller value is a: " << a << endl;
            if( b-a <= epsilon )
                cout << "The numbers are almost equal.\n";
        }
        else
        {
            cout << "The two numbers are equal.\n";            
        }
        cout << '\n';
    }

    return 0;
}


sample output:
Please enter two space-separated doubles (-1 -1 to stop):
 21.9999999 21.9999998
The larger value is a: 21.9999999
The smaller value is b: 21.9999998
The numbers are almost equal.

 21.9999999 21.9999997
The larger value is a: 21.9999999
The smaller value is b: 21.9999997

 21.9999999 21.9999999
The two numbers are equal.

 21.9999998 21.9999999
The larger value is b: 21.9999999
The smaller value is a: 21.9999998
The numbers are almost equal.

 -1 -1
Your program is buggy. You need to check if the difference is <=, not ==.
And you only get a precision of 6 for printing unless you ask for more.

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
#include <iostream>
using namespace std;

int main(){
    double a, b;

    cout.precision(18); // more than it really has

    cout << "Enter two doubles: ";

    while (cin >> a >> b) {

        if (a > b) {
            cout << "The larger value is a:" << a
                 << "\nThe smaller value is b:" << b << '\n'; 
            if (a - b <= 1e-7) {
                cout << "The numbers are almost equal.\n";
            }
        } 
        else if (b > a) {
            cout << "The larger value is b: " << b
                 << "\nThe smaller value is a:" << a << '\n';
            if (b - a <= 1e-7) {
                cout << "The numbers are almost equal.";
            }
        }
        else if (a == b) {
            cout << "The two numbers are equal.\n";
        }

        cout << "Enter two doubles: ";
    }
}


BTW, you wouldn't normally include stdio.h in a C++ program, especially if you are including iostream.
Last edited on
Im literally writing all of this down.
Seriously. You guys are 9999x better than reddit and stackoverflow
there are some good aspects to the StackOverflow stuff. There are so many eyes on every post, that for the most part, especially if it's marked as answer, likely it'll be written in exact language/terminology.

Having too many eyes can, of course, also be a downside. I once tried to help answer a question on the English site and got downvoted for one imprecise word in a whole paragraph of answer. It can be especially harsh when the topic can have more than one answer and the content open to some interpretation. There are quite a few lurkers out in the Stack badlands who still have the mindset of one from a certain country in the 1940s...
^I swear to god if it's Nazi Germany and :"Only the strong survive" or something like that. . . .
You guys are 9999x better than reddit and stackoverflow

Surely that should be 9999.9999999999x.
You guys are 9999x better than reddit and stackoverflow


I believe we are also significantly better looking too :)
Very handsome, have big penis, very big.
Topic archived. No new replies allowed.