You can write a function that will provide a mask to select any number of contiguous bits from a number, starting from a given position.
Below is a demonstration program containing such a function.
#include <iostream> #include <iomanip> unsigned long long get_mask( size_t pos, size_t n ) { return ~( ~0ull << n ) << pos; } int main() { unsigned long long a = 0x12345671FBC00045; unsigned short b; std::cout << std::hex << a << std::endl; for ( size_t i = 0; i < sizeof( a ); i += sizeof( b ) ) { unsigned long long mask = get_mask( 8 * i, 8 * sizeof( b ) ); b = ( a & mask ) >> 8 * i; std::cout << std::hex << b << std::endl; } return 0; }
Output of the program to the console
12345671fbc00045 45 fbc0 5671 1234
In fact, I am the only one who answered your question: :)
And in general, how to allocate any number of bits from a variable and write them to another?
You can generalize this function for any integer type by making it template. For example,
#include <iostream> #include <iomanip> #include <type_traits> template <typename T> T get_mask( size_t pos, size_t n ) { return ~( ~static_cast<typename std::make_unsigned<T>::type>( 0 ) << n ) << pos; } int main() { unsigned long long a = 0x12345671FBC00045; unsigned short b; std::cout << std::hex << a << std::endl; for ( size_t i = 0; i < sizeof( a ); i += sizeof( b ) ) { size_t pos = 8 * i; size_t n = 8 * sizeof( b ); auto mask = get_mask<unsigned long long>( pos, n ); b = ( a & mask ) >> pos; std::cout << "mask = " << std::hex << mask << ", value = " << std::hex << b << std::endl; } return 0; }
The output of the program to the console will be
12345671fbc00045 mask = ffff, value = 45 mask = ffff0000, value = fbc0 mask = ffff00000000, value = 5671 mask = ffff000000000000, value = 1234