I attempted KR exercise 2.1 - determine the range of long
variables by direct calculation.
#include <stdio.h>
#include <limits.h>
int main()
{
unsigned short long_bits = sizeof( long ) * CHAR_BIT;
printf( "LONG_MAX = %ld\n", ( 1L << ( long_bits - 1 ) ) - 1 );
printf( "LONG_MIN = %ld\n", ( -1 ) * ( 1L << ( long_bits - 1 ) ) );
printf( "ULONG_MAX (1) = %lu\n", ( 1UL << long_bits ) - 1 ); // doesn't work
printf( "ULONG_MAX (2) = %lu\n", 2*( 1UL << ( long_bits - 1 ) ) - 1 ); // work
printf( "\n" );
}
ULONG_MAX (1) = 0
is wrong because the left shift overflow I suppose.ULONG_MAX (2) = 18446744073709551615
seems correct by replacing the last left shift with a multiply by 2.
So it appears that left shift operator suffers from overflow, but multiplication does not? Does this intermediate calculation 2*( 1UL << ( long_bits - 1 ) )
promote to some type more than long
? In my machine, long
and long long
are exactly the same ( 8 Bytes ).
Edit:
As Lundin pointed out, all needed for ULONG_MAX
is printf( "ULONG_MAX = %lu\n", ~0L );
Using left shift in this case caused UB, and multiply by 2 is potentially UB, too (although result of case 2 looks correct).