Datatype Sizes and Limits#

Sizes#

When we declare an object in C++, the compiler will reserve memory to hold the data. The amount of memory needed depends on the datatype.

Important

C++ guarantees a minimum size of the different types, but different compilers or processors may have different defaults.

We can explicitly determine this with a C++ program using sizeof()—that returns the number of bytes

std::cout << sizeof(double) << std::endl;

The following is guaranteed:

sizeof(char) == 1 <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)

Tip

If you want to guarantee a size for an int, there are datatypes that explicitly require a fixed width, like int32_t: https://en.cppreference.com/w/cpp/types/integer

Reporting limits#

We can find out a lot about the range and precision of numbers that can be stored with a given type by using std::numeric_limits:

Listing 3 limits_test.cpp#
#include <iostream>
#include <limits>

int main() {

    std::cout << "double: " << std::endl;
    std::cout << "  smallest value = " << std::numeric_limits<double>::min() << std::endl;
    std::cout << "  lowest value = " << std::numeric_limits<double>::lowest() << std::endl;
    std::cout << "  largest value = " << std::numeric_limits<double>::max() << std::endl;

    std::cout << "short: " << std::endl;
    std::cout << "  smallest value = " << std::numeric_limits<short>::min() << std::endl;
    std::cout << "  lowest value = " << std::numeric_limits<short>::lowest() << std::endl;
    std::cout << "  largest value = " << std::numeric_limits<short>::max() << std::endl;

}

Overflow and underflow#

What happens if we exceed the limits of a data type? For floating point, we don’t abruptly transition to 0. (for underflow) but instead start losing digits of precision as subnormal numbers.

For integers, it is more fun:

An XKCD comic showing counting sheep hitting the maximum integer value and rolling over to a negative value.

Fig. 4 (xkcd)#

Try it…

Create a program that initializes a short integer and through addition triggers an overflow.

Floating point precision#

Precision is also important with floating point. Consider the following: what do you expect?

double a = 1.0;
double b = -1.0;
double c = 2.e-15;

std::cout << (a + b) + c << std::endl;
std::cout << a + (b + c) << std::endl;

With floating point, the associate property of addition does not hold.