# Thread: saving specific bits from a 64-bit number

1. ## saving specific bits from a 64-bit number

Hello,

I have a 64-bit uint64_t number:

Code:
`Primitive<uint64_t> b = 0xCCCCCCCC00000000;`
I need to save the first 31 (most important) bits - 7FFFFFFE.

I found this solution in the Internet:

Code:
`start = (((b)>>(first)) & ((1<<(((last+1)-(first))))-1));`
but in my case for this code:

Code:
`Primitive<uint64_t> start = (((b)>>(32)) & ((1<<(((63+1)-(32))))-1));`
I get an error: left shift count >= width of type

And even if I change 63 to 62:

Code:
`Primitive<uint64_t> start = (((b)>>(32)) & ((1<<(((62+1)-(32))))-1));`
I get: error: integer overflow in expression

Any tips? Thanks.

2. That looks like C++, not C. You're in the wrong forum.

In C, the 31 most significant bits of a uint64_t value are simply b shifted right (64-31)=33 bits:
Code:
`uint64_t result = (uint64_t)value >> 33U;`
In general, the right shift count is (number of bits - number of highest bits needed).

If you want to (further) limit the result to fewer bits, mask with ((((type)1) << bits)-1). This works, because mathematically that is 2bits-1, which in binary has bits least significant bits set.

In C, you need to cast to type (uint64_t, above), so that the shift is done with the desired result type. Logically, you need value to first be converted to the result type, and then operated on, not the other way around.

For example, this copies length bits starting from offset (least significant bit numbered 0), into the least significant bits in the result:
Code:
```uint64_t copybits(const uint64_t value, const unsigned char offset, const unsigned char length)
{
if (length < 64U)
return (value >> offset) & ( ( (uint64_t)1 << length) - 1 );
else
return (value >> offset);
}```
The if clause is needed, because (uint64_t)1 << 64) overflows. (It is not used always in practice, because practically all architectures use two's complement rules, and wraparound such that ((uint64_t)1 << 64)-1 == (uint64_t)-1 == ~(uint64_t)0 = all bits set.

With the if clause, the above works on all architectures, and is not dependent on byte order (little or big endian) or even on internal representation of integers. You only need to remember that regardless of byte order, the above uses offset 0 for the least significant bit, increasing towards more important bits (63 for the most significant bit in an uint64_t), and returns the result in least significant bits.

3. Originally Posted by Nominal Animal
That looks like C++, not C. You're in the wrong forum.
Indeed, and... moved.

4. Or instead of (uint64_t)1 you can just write 1ULL.

5. C casts are evil. Seriously. You should use C++ casts. For more information, see Stephan T. Lavavej - Core C&#43;&#43;, 8 of n | C9 Lectures: Stephan T. Lavavej - Core C&#43;&#43; | Channel 9.
Part 7 is also informative since it deals with signed and unsigned issues and conversions between different integer data types.

6. thanks!