I need to merge two variables into one like in example below:
x = 0b110101
y = 0b10011
merged(x,y) -> 0b11010111001
merged(y,x) -> 0b10011101011
So, y
is reversed and concatenated to x
without unnecessary zeros (last bit of result is always 1)
In other words: merged(abcdefg, hijklm)
results in abcdefgmlkjih
where a
and h
are 1
What would be the most efficient way to do this in C
EDIT: most efficient = fastest, sizeof(x)
= sizeof(y)
= 1
, CHAR_BIT
= 8
EDIT2: Since question has been put on hold I will post summary right here: Further limitations and more detail:
Target language: C with 64-bit operations support
For this exact problem fastest method would be a 256 element lookup table as was suggested in comments, which returns index of high bit N
and reversed value of second argument, so we can shift first argument to the left by N
and perform bitwise or
with reversed value of second argument.
In case someone needs good performance for arguments larger than 8 bit (lookup table is not an option) they could:
Find index of high bit using de Bruijn algorithm. Example for 32 bits:
uint32_t msbDeBruijn32( uint32_t v ) { static const int MultiplyDeBruijnBitPosition[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; v |= v >> 1; // first round down to one less than a power of 2 v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; return MultiplyDeBruijnBitPosition[( uint32_t )( v * 0x07C4ACDDU ) >> 27]; }
taken from this question: Find most significant bit (left-most) that is set in a bit array
Reverse bits in bytes (one by one) of the second argument using this bit twiddling hack
unsigned char b; // reverse this (8-bit) byte b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;
taken from here: http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious
So, this question now can be closed/deleted