How to find range of data types in C programming?

In C programming data types play a major role, so is their size and range. The sizeof() operator gives you bytes required to store value of some type in memory. However, in programming you must be aware of range of a type to avoid overflow and underflow errors.

The size of a data type is compiler dependent and so is its range. So, you must not hardcode size and range values in your program.

There are two ways to find minimum and maximum range of a type. You can use any of the approach to get range of a type.

Find range of data types manually without C library

The minimum and maximum range of a signed type is given by –
-(2<sup>N-1</sup>) to 2<sup>N-1</sup> - 1 (Where N is sizeof(type) * 8 i.e. total number of bits used by the type)

The minimum and maximum range of an unsigned type is given by –
0 to (2<sup>N-1</sup>) + (2<sup>N-1</sup> - 1)

Let us check this programmatically.

/**
 * C program to find range of data type
 */

#include <stdio.h>

void printUnsignedRange(int bytes)
{
    int bits = 8 * bytes;
    
    unsigned long long to = (1LLU << (bits - 1)) + ((1LL << (bits - 1)) - 1);;
    
    printf(" 0 to %llu\n\n", to);
}

void printSignedRange(int bytes)
{
    int bits = 8 * bytes;
    
    long long from  = -(1LL << (bits - 1));
    long long to    =  (1LL << (bits - 1)) - 1;
    
    printf(" %lld to %lld\n\n", from, to);
}

int main()
{
    printf("Range of char =");
    printSignedRange(sizeof(char));
    
    printf("Range of unsigned char =");
    printUnsignedRange(sizeof(unsigned char));
    
    printf("Range of short =");
    printSignedRange(sizeof(short));
    
    printf("Range of unsigned short =");
    printUnsignedRange(sizeof(unsigned short));
    
    printf("Range of int =");
    printSignedRange(sizeof(int));
    
    printf("Range of unsigned int =");
    printUnsignedRange(sizeof(unsigned int));
    
    printf("Range of long =");
    printSignedRange(sizeof(long));
    
    printf("Range of unsigned long =");
    printUnsignedRange(sizeof(unsigned long));
    
    printf("Range of long long =");
    printSignedRange(sizeof(long long));
    
    printf("Range of unsigned long long =");
    printUnsignedRange(sizeof(unsigned long long));
    
    return 0;
}

In the above program I have used bitwise left shift << operator to calculate power of 2.

Read more about – Bitwise left shift << operator in C programming

Output

Range of char = -128 to 127

Range of unsigned char = 0 to 255

Range of short = -32768 to 32767

Range of unsigned short = 0 to 65535

Range of int = -2147483648 to 2147483647

Range of unsigned int = 0 to 4294967295

Range of long = -2147483648 to 2147483647

Range of unsigned long = 0 to 4294967295

Range of long long = -9223372036854775808 to 9223372036854775807

Range of unsigned long long = 0 to 18446744073709551615

Find range of data types using C library

The above approach to get range of any type is cool, however not recommended to use. It is always recommended to use the power of pre-defined C library.

In C programming minimum and maximum constants are defined under two header files – limits.h and float.h.

limits.h defines constants related to integer and character types. Such as minimum and maximum size range, total bits etc.

float.h defines constants related to floating point numbers. Such as precision, minimum and maximum size etc.

Let us use the C library to get minimum and maximum range of a data type.

/**
 * C program to get minimum and maximum range of a type using C library constants
 */
#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{
    printf("Range of signed char %d to %d\n", SCHAR_MIN, SCHAR_MAX);
    printf("Range of unsigned char 0 to %d\n\n", UCHAR_MAX);

    printf("Range of signed short int %d to %d\n", SHRT_MIN, SHRT_MAX);
    printf("Range of unsigned short int 0 to %d\n\n", USHRT_MAX);

    printf("Range of signed int %d to %d\n", INT_MIN, INT_MAX);
    printf("Range of unsigned int 0 to %lu\n\n", UINT_MAX);

    printf("Range of signed long int %ld to %ld\n", LONG_MIN, LONG_MAX);
    printf("Range of unsigned long int 0 to %lu\n\n", ULONG_MAX);

    // In some compilers LLONG_MIN, LLONG_MAX
    printf("Range of signed long long int %lld to %lld\n", LONG_LONG_MIN, LONG_LONG_MAX); 
    // In some compilers ULLONG_MAX
    printf("Range of unsigned long long int 0 to %llu\n\n", ULONG_LONG_MAX); 

    printf("Range of float %e to %e\n", FLT_MIN, FLT_MAX);
    printf("Range of double %e to %e\n", DBL_MIN, DBL_MAX);
    printf("Range of long double %e to %e\n", LDBL_MIN, LDBL_MAX);

    return 0;
}

Output

Range of signed char -128 to 127
Range of unsigned char 0 to 255

Range of signed short int -32768 to 32767
Range of unsigned short int 0 to 65535

Range of signed int -2147483648 to 2147483647
Range of unsigned int 0 to 4294967295

Range of signed long int -2147483648 to 2147483647
Range of unsigned long int 0 to 4294967295

Range of signed long long int -9223372036854775808 to 9223372036854775807
Range of unsigned long long int 0 to 18446744073709551615

Range of float 1.175494e-038 to 3.402823e+038
Range of double 2.225074e-308 to 1.797693e+308
Range of long double -0.000000e+000 to -1.#QNAN0e+000