1

So I've come across a strange need to 'merge' two numbers:

byte one;
byte two;

into an int three; with the first bit being the first bit of one, the second bit being the first bit of two, the third being the second bit of one and so on.

So with these two numbers:

01001000
00010001

would result in

0001001001000010


A more didatic illustration of the interlacing operation:

byte one = 0  1  0  0  1  0  0  0
byte two = 0  0  0  1  0  0  0  1
result   = 00 01 00 10 01 00 00 10
2
  • into an int three; with the first bit being the first bit of one, the second bit being the first bit of two, the third being the second bit of one and so on and for 01001000 00010001 it should be according to your explanation this 0010000110000001 but NOT this 0001001001000010! Am I wrong?
    – Yahya
    Commented Nov 18, 2017 at 19:28
  • Hi @Yahya, yes, was my first perception, and make more sense as "standard interlacing"... Check illustration, I edited. As implementarion, no problem, is only a case to swap, using f(b,a) instead f(a,b) in the presented solutions. Commented Aug 19, 2018 at 16:23

2 Answers 2

1

UPDATE: Sorry misread your question completely.

The following code should do:

public static int InterlacedMerge(byte low, byte high)
{
    var result = 0;

    for (var offset = 0; offset < 8; offset++)
    {
        var mask = 1 << offset;
        result |= ((low & mask) | ((high & mask)) << 1) << offset;
    }

    return result;
}

I am not, by any means, very smart when it comes to bit twiddling so there probably is a more efficient way to do this. That said, I think this will do the job but I haven't tested it, so make sure you do.

P.D: There are some unnecessary parenthesis in the code but I'm never sure about bitwise operators precedence so I find it easier to read the way its written.

UPDATE2: Here is the same code a little more verbose to make it easier to follow:

public static int InterlacedMerge(byte low, byte high)
{
    var result = 0;

    for (var offset = 0; offset < 8; offset++)
    {
        //Creates a mask with the current bit set to one: 00000001,
        //00000010, 00000100, and so on...
        var mask = 1 << offset; 

        //Creates a number with the current bit set to low's bit value.
        //All other bits are 0
        var lowAndMask = low & mask; 

        //Creates a number with the current bit set to high's bit value.
        //All other bits are 0
        var highAndMask = high & mask; 

        //Create a merged pair where the lowest bit is the low 's bit value
        //and the highest bit is high's bit value.
        var mergedPair = lowAndMask | (highAndMask << 1);

        //Ors the mergedPair into the result shifted left offset times
        //Because we are merging two bits at a time, we need to
        //shift 1 additional time for each preceding bit.                              
        result |= mergedPair << offset;
    }

    return result;
}
1
  • @Yahya Its standard bit twiddling. I'll make the code more verbose a little to make it more readable.
    – InBetween
    Commented Nov 18, 2017 at 18:37
1

@inbetween answered while I was writing this; similar solution, different phrasing.

You'll have to write a loop. You'll test one bit in each of the two inputs. You'll set a bit in an output for each input. You'll shift all three values one place. Maybe something like this (untested):

#define TOPBIT 32768

for /* 16 times */
    if ( value1 & 1 )  out |= TOPBIT;
    out >>= 1;

    if ( value2 & 1 )  out |= TOPBIT;
    out >>= 1;

    b1 >>= 1;
    b2 >>= 1;

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.