Help with understanding incremented value result

Hey all,

I am working on a research project about integer values. Incrementing them above range, and then decrementing them below range. I've got the basic concepts with int, short int, and long int. But when it comes to float and double I am unsure exactly what is going on. So here is my test code and then the result:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <cmath>
using namespace std;

int main () {
	
	double DoubleMax = 1e308;
	double DoubleMin = 1e-308;
	float floatMax = 1e38;
	float floatMin = 1e-38;

	cout << ++DoubleMax << " double maximum\n";
		cout << endl;
	cout << --DoubleMin << " double minimum\n";
		cout << endl;
	
	cout << ++floatMax << " float maximum\n";
		cout << endl;
	cout << --floatMin << " float minimum\n";
		cout << endl;
	
	return 0;
}


The results for the max value return the initial value, whilst the min value returns a -1. I would really appreciate if someone can help me understand the data flow better.

Thanks!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <limits>

int main()
{
    std::cout << "long long - size: " << sizeof(long long) << " bytes    range: "
              << std::numeric_limits<long long>::min() << " to " << std::numeric_limits<long long>::max() << "\n\n" ;

    std::cout << "double    - size: " << sizeof(double) << " bytes    range: "
              << std::numeric_limits<double>::min() << " to " << std::numeric_limits<double>::max() << "\n\n" ;

    double a = 1.0e+20 ;
    double b = 1.0e-20 ;
    double c = - a ;

    std::cout << "a: "    << a << "    a+1: "    << a+1 << "    a-1: "    << a-1 << "\n\n" ;
    std::cout << "b: "    << b << "    b+1: "    << b+1 << "    b-1: "    << b-1 << "\n\n" ;

    std::cout << "a: "    << a << "    b: "    << b << "    a+b: "    << a+b << "    a-b: "    << a-b << "\n\n" ;

    std::cout << "a: "    << a << "    b: "    << b << "    c: "    << c << "    a+b+c: "    << a+b+c << "    a+c+b: "    << a+c+b << "\n\n" ;
}

clang++ -std=c++14 -stdlib=libc++ -Wall -Wextra -pedantic-errors -Wno-unused -O2 main.cpp -lsupc++ && ./a.out

long long - size: 8 bytes    range: -9223372036854775808 to 9223372036854775807

double    - size: 8 bytes    range: 2.22507e-308 to 1.79769e+308

a: 1e+20    a+1: 1e+20    a-1: 1e+20

b: 1e-20    b+1: 1    b-1: -1

a: 1e+20    b: 1e-20    a+b: 1e+20    a-b: 1e+20

a: 1e+20    b: 1e-20    c: -1e+20    a+b+c: 0    a+c+b: 1e-20


Try to answer these questions and it should lead you to an understanding of floating point.

1. Though a variable of type long long and a variable of type double take up the same amount of memory, the range of a double is (much) larger than that of a long long. How would this be possible?

2. Though 1.0e+20 is much smaller than the maximum value of a double, why is 1.0e+20 + 1 equal to 1.0e+20?
Does your answer to question 1 suggest anything?

3. Why is a+b+c not equal to a+c+b?
Thank you for the reply JLBorges,

Working with other classmates today we are all very stumped by the result when we increment beyond the max range of double and float. And then the result for double and float being decremented below the minimum. We were talking if it had anything to do with their values being true for infinity.

But considering the result for max float and double incremented above range produced the same number (1e38 for example), while the minimum float and double decremented below range produced a -1. This is the big hangup. I could see how incrementing above the range for double and float would possibly stay in the range of infinity, but why would the decrement below range produce a -1?
> we are all very stumped by the result when we increment beyond the max range of double and float.

Repeat: Try to answer these questions and it should lead you to an understanding of floating point.

Here are a few more questions of the same kind:

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

int main()
{
    {
        std::cout << "experiment: what happens when a small number is added to a big number?"
                     "\n=======================================================================\n" ;
        double d = 1.0e12 ;
        const double e = 0.01 ;

        std::cout << std::fixed << std::setprecision(20) ;
        const auto w50 = std::setw(50) ;

        for( int i = 0 ; i < 8 ; ++i, d*=10 )
        {
            std::cout << w50 << d << " +\n" << w50 << e
                      << "\n---------------------------------------------------------\n"
                      << w50 << d+e << "\n\n" ;

            d *= 10 ;
        }

        std::cout << '\n' ;
    }


    {
        std::cout << "\nexperiment: what happens when a big number is subtracted from a small number?"
                     "\n=======================================================================\n" ;
        double d = 1.0e12 ;
        const double e = 0.01 ;

        std::cout << std::fixed << std::setprecision(20) ;
        const auto w50 = std::setw(50) ;

        for( int i = 0 ; i < 8 ; ++i, d*=10 )
        {
            std::cout << w50 << e << " -\n" << w50 << d
                      << "\n-----------------------------------------------------------------\n"
                      << w50 << e-d << "\n\n" ;

            d *= 10 ;
        }

        std::cout << '\n' ;
    }

    {
        std::cout << "\nexperiment: what happens when a big number is incremented?"
                     "\n=======================================================================\n" ;
        double d = 1.0e16 ;

        std::cout << std::fixed << std::setprecision(20) ;
        const auto w50 = std::setw(50) ;

        for( int i = 0 ; i < 8 ; ++i )
        {
            const double e = i+1 ;
            std::cout << w50 << d << " +\n" << w50 << e
                      << "\n-----------------------------------------------------------------\n"
                      << w50 << d+e << "\n\n" ;

        }

        std::cout << '\n' ;
    }
}

http://coliru.stacked-crooked.com/a/b047d5cd1b8e59f2

1. How many distinct values can 64-bits in memory hold?
2. How many real numbers are there between 1 and 10^20? Betweeen 1 and 2?
3. Does the term 'The Pigeon Hole Principle' ring a bell?

4. We have initialised e this way const double e = 0.01 ;. Then why is it printed as 0.01000000000000000021?

5. In 1000000000000.00000000000000000000 + 0.01000000000000000021 == 1000000000000.01000976562500000000,
where have the digits 9765625 come from? What happened to the 21 at the end?

6. Why is 10000000000000000000000 multiplied by 10 yielding 999999999999999983222784?

7. Why are 10000000000000000 + 3, 10000000000000000 + 4 and 10000000000000000 + 5
all giving the same result 10000000000000004 ?
Topic archived. No new replies allowed.