# What is the value of ~0 in C?

9

I want to get the values of `INT_MIN` and `INT_MAX`. I've tried `~0` and `~0 >> 1` since the leftmost bit is a sign bit but I got `-1` for both of them.

It's so confused that why `~0` doesn't turn out to be `0xffffffff` and `~0 >> 1` to be `0x7fffffff`?

c
bit-manipulation
asked on Stack Overflow Apr 20, 2014 by dastan • edited Sep 22, 2019 by phuclv

20

Use:

``````~0U >> 1
``````

Suffix 'U' for unsigned shift behavior.

### so, confused that why not `~0` turns out to be `0xffffffff`?

See, what is `0` say in four bytes representation:

``````BIT NUMBER    31                                     0
▼                                     ▼
number bits    0000 0000 0000 0000 0000 0000 0000 0000
▲                                     ▲
MSB                                   LSB

LSB - Least Significant Bit (numbered 0)
MSB - Most  Significant Bit (numbered 31)
``````

Now `~` is bitwise not operator then flips all bits in `0` as:

``````BIT NUMBER    31                                     0
▼                                     ▼
number bits    1111 1111 1111 1111 1111 1111 1111 1111
▲                                     ▲
MSB                                   LSB
``````

Because of MSB = `1` this representation is treated as negative number and its magnitude is find using 2'complement math that is `-1`.

### How?

What is `1` ? it is:

``````number bits    0000 0000 0000 0000 0000 0000 0000 0001
▲                                     ▲
MSB                                   LSB
``````

1's complement of `1`

``````number bits    1111 1111 1111 1111 1111 1111 1111 1110
▲                                     ▲
MSB                                   LSB
``````

2'complement? Add `1` in one's complement, that is:

``````number bits    1111 1111 1111 1111 1111 1111 1111 1111
▲                                     ▲
MSB                                   LSB
``````

this same as when you gets `~0` ? that is why you are getting `-1` output.

### Now >> shift operator?

In most implementation of C >> operator is defined as an arithmetic right shift, which preserves the sign bit MSB. So `~0 >> 1` is noting but `-1` remains same.

### 6.5.7 [Bitwise shift operators]

5 The result of `E1 >> E2` is `E1` right-shifted `E2` bit positions. If `E1` has an unsigned type or if `E1` has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of `E1 / 2E2`. If `E1` has a signed type and a negative value, the resulting value is implementation-defined.

You requirement is what is called unsigned right shift `>>` and the behavior you needed can be find using unsigned number that is why I suffixed `U` as `0U`.

### How to print INT_MIN and INT_MAX?

Because printing INT_MIN and INT_MAX is bit tricky(because of undefined and implementation behavior of setting MSB and bit-overflow) in C so I have written a code as follows:

``````#include <stdio.h>
#include<limits.h> /* include for CHAR_BIT */
int main(){
int my_int_min = 1U << ((sizeof(int) * CHAR_BIT) - 1);
int my_int_max = ~0U >> 1;
printf("INT_MIN  = %d\n", my_int_min);
printf("INT_MAX  = %d\n", my_int_max);
return 0;
}
``````

See it executing @codepad, it output is:

``````INT_MIN  = -2147483648
INT_MAX  = 2147483647
``````

### How does this code work?

Note for 32-bit number range is `[-2147483648, 2147483647]` that is equals to `[-231, 231 -1 ]`.

INT_MIN: -231 == -2147483648 is:

``````    1000 0000 0000 0000 0000 0000 0000 0000
▲                                     ▲
MSB                                   LSB
``````

In expression `1U << ((sizeof(int) * CHAR_BIT) - 1)`, I shifts first bit the LSB(that is 1) to left most side at MSB, And because in C, setting signed bit is undefined behavior when operand is singed type so I used unsigned one 1U.

### 6.5.7 [Bitwise shift operators]

The result of `E1 << E2` is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2 , reduced modulo one more than the maximum value representable in the result type. 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.

Another point to note is I used CHAR_BIT a standard macro defined in limits.h that tells number of bits in one char in a C implementation (remember: A char is always one byte size but number of bits in one bytes can be different on different system not always guaranteed to be 8).

INT_MAX: 231 -1 == 2147483647

``````    0111 1111 1111 1111 1111 1111 1111 1111
▲                                     ▲
MSB                                   LSB
``````
answered on Stack Overflow Apr 20, 2014 by Grijesh Chauhan • edited Apr 20, 2014 by Grijesh Chauhan
4

0 is of type `int`. So are `~0` and `~0 >> 1` because int type promotion

~0 is all 1s and it's -1 in 2's complement, which is the default representation of most modern implementations.

Right shift in C is implementation defined. But most implementations define `>>` as arithmetic shift when the type is signed and logical shift when the type is unsigned

Since `~0` is `int`, which is signed type, `~0 >> 1` will be arithmetic shift right. Hence the value is sign extended, cause the value to be all 1s

You need to do `unsigned(~0) >> 1`

There are no way to get INT_MIN and INT_MAX because in C there are 3 different signed type implementations

answered on Stack Overflow Apr 20, 2014 by phuclv
1

numbers are stored in 2's compliment so `~0` is `0XFFFFFFFF` which is -1 .
so `FFFFFFF(1111) >>1` gives `(1111)FFFFFFF` = `0XFFFFFFFF` = `-1`.

When shifting an `unsigned` value, the `>>` operator in C is a `logical shift`. When shifting a `signed` value, the `>>` operator is an `arithmetic shift`.
So , `~0U >> 1` gives `(1111)FFFFFFF` = `0XFFFFFFFF` .

answered on Stack Overflow Apr 20, 2014 by Aseem Goyal • edited Apr 20, 2014 by Aseem Goyal
1

`~0` is `-1`. Every C implementation that you're likely to run into uses two's complement for signed integers, so `0xffffffff` is `-1` (assuming 32-bit integers). `~0 >> 1` is the equivalent of dividing `-1` by `2`; since we're doing integer arithmetic, the result is `-1`.

answered on Stack Overflow Apr 20, 2014 by user3553031
1

The value of an all bit set `int` depends on the sign representation that your platform has for `int`. This is why the macros `INT_MIN` and `INT_MAX` were invented, there is no way of computing these values in a portable way.

answered on Stack Overflow Apr 20, 2014 by Jens Gustedt
1

Based on the wikipedia article, C normally implements an arithmetic shift. That means that when you right-shift the quantity `0xffffffff`, the left-most bit (sign bit) of `1` will be preserved, as you observe.

However, Wikipedia also mentions the following, so you will get a logical shift (result of `0x7fffffff`) if you use the unsigned type.

The >> operator in C and C++ is not necessarily an arithmetic shift. Usually it is only an arithmetic shift if used with a signed integer type on its left-hand side. If it is used on an unsigned integer type instead, it will be a logical shift.

answered on Stack Overflow Apr 20, 2014 by merlin2011
1

On a 32bit system, `0` is `0x00000000`. `~` is the bitwise not operator, which turns every `0` bit to `1` and vice versa. Therefore, `~0` (`~0x00000000`) gives `0xffffffff`.

This in turn is interpreted as `-1` in Two's complement.

answered on Stack Overflow Apr 20, 2014 by Olaf Dietsche

User contributions licensed under CC BY-SA 3.0