What's wrong with the code above?
1 << (bits-1)
is shifting the integer constant of type int
outside its range and leads to integer overflow and undefined behavior.
You may want to consider shifting a long long
rather than an int
.
1LL << (bits-1)
Yet this too is integer overflow and undefined behavior as it shifts the 1 outside the long long
range.
The result of E1 << E2 is E1 left-shifted E2 bit positions; ... If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined. C11dr §6.5.7 4
To portable find the range of long long
, use LLONG_MIN, LLONG_MAX
from <limit.h>
.
#include <limit.h>
printf("%d bytes from %lld to %lld\n", bytes, LLONG_MIN, LLONG_MAX);
If long long
lacks padding, (something very very common, by not required by C), the below will print the max value of long long
.
#include <limit.h>
int main(void) {
long long max;
int bytes = sizeof(long long);
int bits = CHAR_BIT * bytes;
long long max_halfish = 1LL << (bits-2);
long long max = (max_halfish - 1) + max_halfish;
printf("max %lld\n", max);
}
min
is simply (-max - 1)
if we assume the very common 2's complement coding.