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