I have managed to get rid of the first couple of bits but how would I only keep only the 6 most significant bits in C? I have tried ((num << 6) & 1)
with no luck
-
2Try working out some examples on paper. Do you want those bits as the top 6 bits of the result, or the bottom 6 bits? – Nate Eldredge Sep 20 '21 at 00:57
-
1@NateEldredge I want them as the top 6 bits (the 6 most significant bits) – regexfun Sep 20 '21 at 00:58
-
1Okay, then hint: you only need to `&` with an appropriate constant. – Nate Eldredge Sep 20 '21 at 00:59
-
@NateEldredge so I don't even need to shift 6 bits to the left? I just need the & operator? – regexfun Sep 20 '21 at 01:01
-
The bits you want are already in exactly the right place, so why would you shift them? You just need to clear all the remaining bits to 0. – Nate Eldredge Sep 20 '21 at 01:02
-
@NateEldredge I see, so would I just use the & operator with a 1 for the first 6 bits? – regexfun Sep 20 '21 at 01:04
-
1So you didn't work out the examples on paper, right? Just go do that. It will help you understand. – Cheatah Sep 20 '21 at 01:05
-
@0___________: Test that and see what you get. – Eric Postpischil Sep 20 '21 at 02:06
-
@EricPostpischil obvious mistake (minus one is needed) as in my answer – 0___________ Sep 20 '21 at 09:16
3 Answers
To get the most significant six bits of an integer and not the rest, bitwise AND it with a mask with the high six bits set and the rest clear.
Because unsigned int
is a pure binary type, its maximum value, UINT_MAX
, has all its bits set. Then UINT_MAX >> 6
shifts those to the right, producing a result with the high six bits clear and the rest set. Performing a bitwise NOT, ~ (UINT_MAX >> 6)
, produces a result with the high six bits set and the rest clear.
Then num & ~ (UINT_MAX >> 6)
produces the high six bits of num
with the remaining bits clear.
UINT_MAX
is declared in <limits.h>
. Due to C’s wrapping arithmetic for unsigned types, you can also get the maximum value of an unsigned int
by using -1u
, so num & ~ (-1u >> 6)
will also work.

- 195,579
- 13
- 168
- 312
Universal method not depending on the width of the integer
#define C6B(num) ((num) & ~((1ull << (sizeof(num) * CHAR_BIT - 6)) - 1))

- 60,014
- 4
- 34
- 74
-
`~(x-1)` is `-x`, so `~((1ull << (sizeof(num) * CHAR_BIT - 6)) - 1))` is more simply `-1ull << sizeof (num) * CHAR_BIT - 6`. However, this is not universal since `unsigned long long` is not necessarily the widest type. `-1ull` could be replaced by `(uintmax_t) -1` or `-UINTMAX_C(1)` or `0*(num)-1u` or `(0?(num):-1u)`. – Eric Postpischil Sep 20 '21 at 13:08
OP wanted the 6 MSbits left in their original place. Other answers address that.
If we want these shifted into the least significant place, a common solution would look like the following. This assumes that an unsigned
has 32 bits. Although common, this is not specified by C.
num >> (32 - 6)
Alternatively we could use the below. This assumes there are no padding bits, which is very common for unsigned
.
#include <limits.h>
num >> (sizeof num * CHAR_BIT - 6)
Alternatively we could make no assumptions and determine bit width from UINT_MAX
and value bits of an integer type:
// Bits in a MAX integer type
// https://stackoverflow.com/a/4589384/2410359
#define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12))
#include <limits.h>
#define UINT_VALUE_BITS IMAX_BITS(UINT_MAX)
num >> (UINT_VALUE_BITS - 6)

- 143,097
- 13
- 135
- 256