Exercise 2-1. Write a program to determine the ranges of char, short, int, and long variables, both signed and unsigned, by printing appropriate values from standard headers and by direct computation. Harder if you compute them: determine the ranges of the various floating-point types.
#include <stdio.h> // for printf()
#include <limits.h>
#include <float.h>
int main()
{
printf("CHAR_BIT: %d\n", CHAR_BIT);
printf("signed char: [%d, %d]\n", SCHAR_MIN, SCHAR_MAX);
printf("char: [%d, %d]\n", CHAR_MIN, CHAR_MAX);
printf("unsigned char: [0, %d]\n", UCHAR_MAX);
printf("short: [%d, %d]\n", SHRT_MIN, SHRT_MAX);
printf("unsigned short: [0, %d]\n", USHRT_MAX);
printf("int: [%d, %d]\n", INT_MIN, INT_MAX);
printf("unsigned int: [0, %u]\n", UINT_MAX);
printf("long int: [%ld, %ld]\n", LONG_MIN, LONG_MAX);
printf("unsigned long: [0, %lu]\n", ULONG_MAX);
printf("long long int: [%lld, %lld]\n", LLONG_MIN, LLONG_MAX);
printf("unsigned long long: [0, %llu]\n", ULLONG_MAX);
printf("FLT_DIG: %d, DBL_DIG: %d, LDBL_DIG: %d\n", FLT_DIG, DBL_DIG, LDBL_DIG);
printf("FLT_DECIMAL_DIG: %d, DBL_DECIMAL_DIG: %d, LDBL_DECIMAL_DIG: %d\n",
FLT_DECIMAL_DIG, DBL_DECIMAL_DIG, LDBL_DECIMAL_DIG);
printf("DECIMAL_DIG: %d\n", DECIMAL_DIG);
printf("FLT_MIN_10_EXP: %d, DBL_MIN_10_EXP: %d, LDBL_MIN_10_EXP: %d\n",
FLT_MIN_10_EXP, DBL_MIN_10_EXP, LDBL_MIN_10_EXP);
printf("FLT_MAX_10_EXP: %d, DBL_MAX_10_EXP: %d, LDBL_MAX_10_EXP: %d\n",
FLT_MAX_10_EXP, DBL_MAX_10_EXP, LDBL_MAX_10_EXP);
printf("FLT_MIN_EXP: %d, DBL_MIN_EXP: %d, LDBL_MIN_EXP: %d\n",
FLT_MIN_EXP, DBL_MIN_EXP, LDBL_MIN_EXP);
printf("FLT_MAX_EXP: %d, DBL_MAX_EXP: %d, LDBL_MAX_EXP: %d\n",
FLT_MAX_EXP, DBL_MAX_EXP, LDBL_MAX_EXP);
printf("FLT_EPSILON: %g, DBL_EPSILON: %g, LDBL_EPSILON: %Lg\n",
FLT_EPSILON, DBL_EPSILON, LDBL_EPSILON);
printf("FLT_TRUE_MIN: %g, DBL_TRUE_MIN: %g, LDBL_TRUE_MIN: %Lg\n",
FLT_TRUE_MIN, DBL_TRUE_MIN, LDBL_TRUE_MIN);
printf("FLT_RADIX (Radix of exponent representation): %d\n", FLT_RADIX);
printf("float: %d mantissa digits\t", FLT_MANT_DIG);
printf("[%g, %g]\n", FLT_MIN, FLT_MAX);
printf("double: %d mantissa digits\t", DBL_MANT_DIG);
printf("[%g, %g]\n", DBL_MIN, DBL_MAX);
printf("long double: %d mantissa digits\t", LDBL_MANT_DIG);
printf("[%Lg, %Lg]\n", LDBL_MIN, LDBL_MAX);
return 0;
}
/*
gcc -E sizes.c // preprocess to show the contents of header files
// On disk: /usr/include/limits.h, /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h,
// /usr/lib/gcc/x86_64-linux-gnu/9/include/float.h
gcc sizes.c -o sizes
./sizes
CHAR_BIT: 8
signed char: [-128, 127]
char: [-128, 127]
unsigned char: [0, 255]
short: [-32768, 32767]
unsigned short: [0, 65535]
int: [-2147483648, 2147483647]
unsigned int: [0, 4294967295]
long int: [-9223372036854775808, 9223372036854775807]
unsigned long: [0, 18446744073709551615]
long long int: [-9223372036854775808, 9223372036854775807]
unsigned long long: [0, 18446744073709551615]
FLT_DIG: 6, DBL_DIG: 15, LDBL_DIG: 18
FLT_DECIMAL_DIG: 9, DBL_DECIMAL_DIG: 17, LDBL_DECIMAL_DIG: 21
DECIMAL_DIG: 21
FLT_MIN_10_EXP: -37, DBL_MIN_10_EXP: -307, LDBL_MIN_10_EXP: -4931
FLT_MAX_10_EXP: 38, DBL_MAX_10_EXP: 308, LDBL_MAX_10_EXP: 4932
FLT_MIN_EXP: -125, DBL_MIN_EXP: -1021, LDBL_MIN_EXP: -16381
FLT_MAX_EXP: 128, DBL_MAX_EXP: 1024, LDBL_MAX_EXP: 16384
FLT_EPSILON: 1.19209e-07, DBL_EPSILON: 2.22045e-16, LDBL_EPSILON: 1.0842e-19
FLT_TRUE_MIN: 1.4013e-45, DBL_TRUE_MIN: 4.94066e-324, LDBL_TRUE_MIN: 3.6452e-4951
FLT_RADIX (Radix of exponent representation): 2 // base 2 (binary)
float: 24 mantissa digits [1.17549e-38, 3.40282e+38]
double: 53 mantissa digits [2.22507e-308, 1.79769e+308]
long double: 64 mantissa digits [3.3621e-4932, 1.18973e+4932]
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for printf()
#include <limits.h>
// integral limits, including char
int main()
{
unsigned char c = -1;
printf("unsigned char(-1):\t%d\n", c);
printf("UCHAR_MAX:\t\t%d\n", UCHAR_MAX);
c = UCHAR_MAX+1; // compiler warning: overflow
printf("unsigned char(UCHAR_MAX+1):\t%d\n", c);
c = 256; // compiler warning: overflow
printf("unsigned char(256):\t\t%d\n", c);
printf("CHAR_MAX:\t %d\n", CHAR_MAX);
printf("CHAR_MIN:\t%d\n", CHAR_MIN);
printf("-CHAR_MAX-1:\t%d\n", -CHAR_MAX-1);
printf("SHRT_MAX:\t %d\n", SHRT_MAX);
printf("SHRT_MIN:\t%d\n", SHRT_MIN);
printf("-SHRT_MAX-1:\t%d\n", -SHRT_MAX-1);
printf("INT_MAX:\t %d\n", INT_MAX);
printf("INT_MIN:\t%d\n", INT_MIN);
printf("-INT_MAX-1:\t%d\n", -INT_MAX-1);
printf("-1:\t\t%u\n", -1); // UINT_MAX
printf("UINT_MAX:\t%u\n", UINT_MAX);
printf("unsigned int min: %u\n", UINT_MAX+1);
printf("-2:\t\t%u\n", -2); // UINT_MAX-1
printf("UINT_MAX-1:\t%u\n", UINT_MAX-1);
printf("LONG_MAX:\t %ld\n", LONG_MAX);
printf("LONG_MIN:\t%ld\n", LONG_MIN);
printf("-LONG_MAX-1:\t%ld\n", -LONG_MAX-1);
printf("-1L:\t\t%lu\n", -1L); // ULONG_MAX
printf("ULONG_MAX:\t%lu\n", ULONG_MAX);
printf("unsigned long min: %lu\n", ULONG_MAX+1);
printf("LLONG_MAX:\t %Ld\n", LLONG_MAX);
printf("LLONG_MIN:\t%Ld\n", LLONG_MIN);
printf("-LLONG_MAX-1:\t%Ld\n", -LLONG_MAX-1);
printf("-1LL:\t\t%Lu\n", -1LL); // ULLONG_MAX
printf("ULLONG_MAX:\t%Lu\n", ULLONG_MAX);
printf("unsigned long long min: %Lu\n", ULLONG_MAX+1);
return 0;
}
/*
gcc intlimits.c -o intlimits
intlimits.c: In function ‘main’:
intlimits.c:10:7: warning: unsigned conversion from ‘int’ to
‘unsigned char’ changes value from ‘256’ to ‘0’ [-Woverflow]
10 | c = UCHAR_MAX+1; // compiler warning: overflow
| ^~~~~~~~~
intlimits.c:12:7: warning: unsigned conversion from ‘int’ to
‘unsigned char’ changes value from ‘256’ to ‘0’ [-Woverflow]
12 | c = 256; // compiler warning: overflow
| ^~~
./intlimits
unsigned char(-1): 255
UCHAR_MAX: 255
unsigned char(UCHAR_MAX+1): 0
unsigned char(256): 0
CHAR_MAX: 127
CHAR_MIN: -128
-CHAR_MAX-1: -128
SHRT_MAX: 32767
SHRT_MIN: -32768
-SHRT_MAX-1: -32768
INT_MAX: 2147483647
INT_MIN: -2147483648
-INT_MAX-1: -2147483648
-1: 4294967295
UINT_MAX: 4294967295
unsigned int min: 0
-2: 4294967294
UINT_MAX-1: 4294967294
LONG_MAX: 9223372036854775807
LONG_MIN: -9223372036854775808
-LONG_MAX-1: -9223372036854775808
-1L: 18446744073709551615
ULONG_MAX: 18446744073709551615
unsigned long min: 0
LLONG_MAX: 9223372036854775807
LLONG_MIN: -9223372036854775808
-LLONG_MAX-1: -9223372036854775808
-1LL: 18446744073709551615
ULLONG_MAX: 18446744073709551615
unsigned long long min: 0
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for printf(), putchar()
#include <string.h> // for strlen()
int main()
{
printf("sizeof(char) = %lu\n", sizeof(char));
printf("sizeof(unsigned char) = %lu\n", sizeof(unsigned char));
printf("sizeof(short) = %lu\n", sizeof(short));
printf("sizeof(int) = %lu\n", sizeof(int));
printf("sizeof(long) = %lu\n", sizeof(long));
printf("sizeof(long long) = %lu\n", sizeof(long long));
printf("sizeof(float) = %lu\n", sizeof(float));
printf("sizeof(double) = %lu\n", sizeof(double));
printf("sizeof(long double) = %lu\n", sizeof(long double));
putchar('\n');
printf("strlen(\"Hello\") = %lu\n", strlen("Hello")); // string length
printf("sizeof(\"Hello\") = %lu\n", sizeof("Hello")); // count ending '\0'
char hello[10] = "Hello";
printf("strlen(hello) = %lu\n", strlen(hello));
printf("sizeof(hello) = %lu\n", sizeof(hello));
return 0;
}
/*
gcc sizeof.c -o sizeof
./sizeof
sizeof(char) = 1 // 1 byte
sizeof(unsigned char) = 1
sizeof(short) = 2
sizeof(int) = 4
sizeof(long) = 8
sizeof(long long) = 8
sizeof(float) = 4
sizeof(double) = 8
sizeof(long double) = 16
strlen("Hello") = 5
sizeof("Hello") = 6
strlen(hello) = 5
sizeof(hello) = 10
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for printf()
#include <limits.h>
#include <math.h> // for pow()
// computed integral limits, including char
int main()
{
int size = pow(2,sizeof(char)*8-1)-1;
printf("2^(sizeof(char)*8-1)-1:\t\t %d\n", size);
printf("CHAR_MAX:\t\t\t %d\n", CHAR_MAX);
size = -pow(2,sizeof(char)*8-1);
printf("-2^(sizeof(char)*8-1):\t\t%d\n", size);
printf("CHAR_MIN:\t\t\t%d\n", CHAR_MIN);
size = pow(2,sizeof(char)*8)-1;
printf("2^(sizeof(char)*8)-1:\t\t %d\n", size);
printf("UCHAR_MAX:\t\t\t %d\n", UCHAR_MAX);
size = pow(2,sizeof(short)*8-1)-1;
printf("2^(sizeof(short)*8-1)-1:\t %d\n", size);
printf("SHRT_MAX:\t\t\t %d\n", SHRT_MAX);
size = -pow(2,sizeof(short)*8-1);
printf("-2^(sizeof(short)*8-1):\t\t%d\n", size);
printf("SHRT_MIN:\t\t\t%d\n", SHRT_MIN);
size = pow(2,sizeof(short)*8)-1;
printf("2^(sizeof(short)*8)-1:\t\t %d\n", size);
printf("USHRT_MAX:\t\t\t %d\n", USHRT_MAX);
size = pow(2,sizeof(int)*8-1)-1;
printf("2^(sizeof(int)*8-1)-1:\t\t %d\n", size);
printf("INT_MAX:\t\t\t %d\n", INT_MAX);
size = -pow(2,sizeof(int)*8-1);
printf("-2^(sizeof(int)*8-1):\t\t%d\n", size);
printf("INT_MIN:\t\t\t%d\n", INT_MIN);
unsigned usize = pow(2,sizeof(int)*8)-1;
printf("2^(sizeof(int)*8)-1:\t\t %u\n", usize);
printf("UINT_MAX:\t\t\t %u\n", UINT_MAX);
long int lsize = pow(2,sizeof(long)*8-1)-1;
printf("2^(sizeof(long)*8-1)-1:\t\t %ld\n", lsize);
printf("LONG_MAX:\t\t\t %ld\n", LONG_MAX);
lsize = -pow(2,sizeof(long)*8-1);
printf("-2^(sizeof(long)*8-1):\t\t%ld\n", lsize);
printf("LONG_MIN:\t\t\t%ld\n", LONG_MIN);
unsigned long int ulsize = pow(2,sizeof(long)*8)-1;
printf("2^(sizeof(long)*8)-1:\t\t %lu\n", ulsize);
printf("ULONG_MAX:\t\t\t %lu\n", ULONG_MAX);
long long int llsize = pow(2,sizeof(long long)*8-1)-1;
printf("2^(sizeof(long long)*8-1)-1:\t %lld\n", llsize);
printf("LLONG_MAX:\t\t\t %lld\n", LLONG_MAX);
llsize = -pow(2,sizeof(long long)*8-1);
printf("-2^(sizeof(long long)*8-1):\t%lld\n", llsize);
printf("LLONG_MIN:\t\t\t%lld\n", LLONG_MIN);
unsigned long long int ullsize = pow(2,sizeof(long long)*8)-1;
printf("2^(sizeof(long long)*8)-1:\t %llu\n", ullsize);
printf("ULLONG_MAX:\t\t\t %llu\n", ULLONG_MAX);
return 0;
}
/*
gcc computed.c -o computed -lm // link math library
// warnings: conversion from double to long
./computed
2^(sizeof(char)*8-1)-1: 127
CHAR_MAX: 127
-2^(sizeof(char)*8-1): -128
CHAR_MIN: -128
2^(sizeof(char)*8)-1: 255
UCHAR_MAX: 255
2^(sizeof(short)*8-1)-1: 32767
SHRT_MAX: 32767
-2^(sizeof(short)*8-1): -32768
SHRT_MIN: -32768
2^(sizeof(short)*8)-1: 65535
USHRT_MAX: 65535
2^(sizeof(int)*8-1)-1: 2147483647
INT_MAX: 2147483647
-2^(sizeof(int)*8-1): -2147483648
INT_MIN: -2147483648
2^(sizeof(int)*8)-1: 4294967295
UINT_MAX: 4294967295
2^(sizeof(long)*8-1)-1: 9223372036854775807
LONG_MAX: 9223372036854775807
-2^(sizeof(long)*8-1): -9223372036854775808
LONG_MIN: -9223372036854775808
2^(sizeof(long)*8)-1: 18446744073709551615
ULONG_MAX: 18446744073709551615
2^(sizeof(long long)*8-1)-1: 9223372036854775807
LLONG_MAX: 9223372036854775807
-2^(sizeof(long long)*8-1): -9223372036854775808
LLONG_MIN: -9223372036854775808
2^(sizeof(long long)*8)-1: 18446744073709551615
ULLONG_MAX: 18446744073709551615
*/