Data types of the variables

As the name suggests, data type represents the name of the type of data. In C++, when creating any variable, we need to specify its data type so that the compiler knows how much memory should be allocated for that particular variable. Such a language, where the programmer needs to tell the compiler the data type of the variable at the compile time, is called a statically-typed language.

In the previous chapter, we only used the int data type that stores only an integer value. Let’s learn about the primitive data typesdata types that are native to the language and do not require user definition in C++.

Data types can be subdivided into integral and floating-point data types.

Integral data types include whole numbers or integers only, whereas floating-point data types include decimal numbers.

The respective allocated sizes and the value ranges of each integral data type are given in the table below:

Integral

Data type

Size in bytes

Values range


int


4


-231 to 231-1

-2147483648 to +2147483647


char


1


-27 to 27-1

-128 to +127


bool


1


0 or 1

true or false

void

1

-


Counting the number of possible different numbers

It is not hard to show that if you have a two digits number with decimal digits, where every digit could be any value between 090-9, the total possibility for this number could be 10×10=10010 \times 10 = 100, represented as 00,01,02,...,9900, 01, 02, ..., 99. Furthermore, for a base 5 representation, we’re allowed to use digits between 040-4. Since we have 5 unique digits to choose from for both places of a two-digit number, we get 5×5=255 \times 5 = 25 possibilities for such a number. This numeric range starts from 00,01,02,03,04,10,...00, 01, 02, 03, 04, 10, ... and ends at 4444. It’s important to understand that we jumped from 0404 to 1010 since we ran out of unique digits. Similarly, for a base 2 number, we’ll have 2×22 \times 2 possibilities since we are only allowed to use the digits 00 and 11 that would produce the number range 00,01,10,1100, 01, 10, 11.

Generally speaking, if we have an nn digit number in a base bb where the total number of symbols for each place is from 0,1,...,b10, 1, ... , b-1 for each digit, then the total possibilities of the nn digit number will be b×b×...×b=bnb \times b \times ... \times b = b^n (bb multiplied nn times) and its range will be from 00 to bn1b^n-1 (in decimal). In base bb it will be from 0 to all the nn digits with value b1b-1.

Hence, the byte is an 8 digit number with base 2, hence having the total number of possibilities as 282^{8} ranging from 00000000,00000001,00000010,00000011,...,1111111100000000, 00000001, 00000010, 00000011, ... , 11111111 for the representation of 00 till 281=2552^8-1 = 255.

Similarly, for any TT-byte integral data type, the total number of possibilities in base 2 should be 2T×82^{T\times 8}.


The respective allocated sizes and the value ranges of each floating-point data type are given in the table below:

Floating-point

Data type

Size in bytes

Values range

float

4

(-3.4 * 1038) to (+3.4 * 1038)

(~7digit)

double

8

(-1.7 * 10308) to (+1.7 * 10308)

(~15digit)

long double

8

(-1.7 * 10308) to (+1.7 * 10308)

(~15digit)

Here is an example from which the size of these data types can be determined.

Press + to interact
#include<iostream>
using namespace std;
int main()
{
cout << "Size of char: " << sizeof(char) << " byte" << endl;
cout << "Size of bool: " << sizeof(bool) << " byte" << endl;
cout << "Size of int: " << sizeof(int) << " bytes" << endl;
cout << "Size of float: " << sizeof(float) << " bytes" << endl;
cout << "Size of double: " << sizeof(double)<< " bytes" << endl;
return 0;
}

The sizes of these data types may vary depending on the machine’s architecture (32-bit or 64-bit) and the compiler we use.

To determine the size of the data type, we used sizeof on the name of the data type. We can also use sizeof on the name of the variable.

Now, let us write code to determine the possible maximum and minimum values of the int data type.

Press + to interact
#include<iostream>
#include <limits.h>
using namespace std;
int main()
{
// print the range of int
cout << "maximum value of int:" << INT_MAX << endl;
cout << "minimum value of int:" << INT_MIN << endl;
// Initialize variable
int value1 = INT_MAX;
// Display variable value
cout << value1 << endl;
// Initialize variable
int value2 = INT_MIN;
// Display variable value
cout << value2;
return 0;
}

If we run the code above, we see that 2147483647 is the maximum value that can be stored in an int type of variable.

We can also see that when printing a number greater than the maximum, say, with a value equal to 2147483649, it prints -2147483647 and not the actual value.

While we print a value within its range, it prints the value just fine.

So to handle cases where we need values greater than the maximum range of a data type, we can use data type modifiers.

We have to include #include<limits.h> to use the predefined constants in the header files for INT_MAX, INT_MIN and several other limits of predefined data types.

Data type modifiers

We can modify the ranges and the amount of allocated space of data types using the data type modifiers. We can use type modifiers with the int, double, and char data types. The type modifiers include:

  • short: It’s used with int. It decreases the size to 2 bytes
  • long: It’s used with int and double. It increases the size by 4 bytes.
    • The size of a long int would be 4 bytes in a 32-bit machine and 8 bytes on a 64-bit machine.
  • signed: It’s used with char and int. It allows us to store both positive and negative values. For a signed int, the range is from -2,147,483,648 to 2,147,483,647. For a signed char, the range is from -128 to 127.
  • unsigned: It’s used with char and int. It allows us to store positive values only. For an unsigned int, the range is from 0 to 4294967295. For an unsigned char, the range is from 0 to 255.

The animation below shows the size and range of the int data type. The int data type is signed by default which means that it can represent positive as well as negative numbers.

The int data type

The int memory is of 44 bytes. Therefore, it has a binary bit representation of 64 bits and its total number of representation power is 2642^{64}. We can use a signed and unsigned int.

  • signed int or int: Due to the last bit reserved for a sign, for example, if the last bit is 11, the value stored in the remaining 3131 bits are -ve, hence a range of 231-2^{31} to +ve range of 23112^{31} - 1. We subtracted 1 because we need to include 00 in the +ve range.
  • unsigned int: Here, there is no sign bit, therefore, all the bits are represented as +ve numbers. The range will be as much as 3232 bits can store, i.e., 00 to 23212^{32}-1.

The char data type

The char data type is of 1 byte, hence its signed representation has the range 27-2^7 to 2712^7-1, and its unsigned char representation has a range of 00 to 2812^8-1.

The animation below shows the size and range of the char data type. The char data type behaves as unsigned by default.

The bool data type

Though bool is a one-byte memory, it stores only 0 or 1 values inside; zero is considered as false, and 1 is considered as true.

The animation below shows the size and range of the bool data type.

The float data type

The float data type is also a 4-byte memory. It reserves one byte for a sign, 8 bits for saving the exponent, and the remaining 23 bits for the significant. That makes it store the largest floating value of ±3.40282×1038\pm 3.40282 \times 10^{38}, both the +ve and -ve values, and the smallest possible floating value of ±1.17549×1038\pm 1.17549 \times 10^{-38}.

The animation below shows the size and range of the float data type.

The double data type

The double data type is an 8-byte floating memory. Hence, its range is large.

Explore the animation below. It shows the size and range of the double data type.

Other data types

There are other data types that are worth exploring. For example the long long data type is an integer of 8 bytes, hence, a larger number of possible representations of 2642^{64}. Similarly, there is a long double data type that has 16 bytes and larger ranges.

The long data type is the short form of long int or long long int. Similarly, short is the short form of short int.

Explore the ranges of data types

Run the program below, and explore the ranges of each data type.

#include<iostream>
#include <limits.h>
#include <float.h>
using namespace std;
int main()
{

cout << "size of short int: "<<sizeof(short)<<endl;
cout << "size of short int: "<<sizeof(short int)<<endl;
cout << "size of long: "<<sizeof(long)<<endl;
cout << "size of long int: "<<sizeof(long int)<<endl;
cout << "size of int: "<<sizeof (int)<<endl;
cout << "size of float : "<< sizeof(float)<<endl;
cout << "size of double : "<< sizeof(double)<<endl;
cout << "Storage size for long double : "<< sizeof(long double)<<endl;
cout << "size of char: "<<sizeof(char)<<endl;
cout << "size of unsigned char: "<<sizeof(unsigned char)<<endl;


// range of byte
cout << "maximum value of unsigned char:" << UCHAR_MAX << endl;
cout << "minimum value of unsigned char:" << 0 << endl;

// range of char
cout << "maximum value of char:" << CHAR_MAX << endl;
cout << "minimum value of char:" << CHAR_MIN << endl;

// range of short char
cout << "maximum value of short char:" << SCHAR_MAX << endl;
cout << "minimum value of short char:" << SCHAR_MIN << endl;

// range of short int
cout << "maximum value of short int:" << SHRT_MAX << endl;
cout << "minimum value of short int:" << SHRT_MIN << endl;

// range of long int
cout << "maximum value of long int:" << LONG_MAX << endl;
cout << "minimum value of long int:" << LONG_MIN << endl;

// range of long long int

cout << "maximum value of long long int:" << LLONG_MAX << endl;
cout << "minimum value of long long int:" << LLONG_MIN << endl;

// range of unsigned int from 0 to 4294967295
cout << "maximum value of unsigned int:" << UINT_MAX << endl;

cout << "______________________________________"<<endl<<endl;
cout << "Floating Data type"<<endl;
cout << "FLT_MAX     :   "<< FLT_MAX<<endl;
cout << "FLT_MIN     :   "<< FLT_MIN<<endl;
cout << "-FLT_MAX    :   "<< -FLT_MAX<<endl;
cout << "-FLT_MIN    :   "<< -FLT_MIN<<endl;
cout << "DBL_MAX     :   "<<  DBL_MAX<<endl;
cout << "DBL_MIN     :   "<<  DBL_MIN<<endl;
cout << "-DBL_MAX     :  "<<  -DBL_MAX<<endl;
cout << "Precision value: "<< FLT_DIG <<endl;
cout << "Floating Value is: "<< FLT_DIG+1 <<" digits (including one digit before point)"<<endl;

cout << "Double Precision value: "<< DBL_DIG <<endl;
cout << "Double Value is: "<< DBL_DIG+1 <<" digits (including one digit before point)"<<endl;
cout << "______________________________________"<<endl<<endl;
cout << "Long Double Data type"<<endl;
cout << "long Double Minimum: "<< LDBL_MIN <<endl;
cout << "long Double Maximum,: "<< LDBL_MAX <<endl;

  return 0;
}





Printing ranges of different data types

There is no need to remember the range. We can use the above code to see the ranges.

Data types

1

There is a data type, known as the long long data type, which is 8 bytes.

How many bits will there be in 8 bytes?

A)

16

B)

64

C)

282^{8}

Question 1 of 30 attempted