views:

1522

answers:

4

Hello,

I'm trying to insert a single bit into an array of bytes, which would shift all the bits in the byte array to the left.

Say I have a Java byte array as follows:

byte[] byteArray = new byte[2];
byteArray[0] = 0x11
byteArray[1] = 0x00

In binary, this byte array represented as:

0001 0001 0000 0000

Now I want to insert a zero in the third bit position (losing the last bit in the byte array), resulting in:

0000 1000 1000 0000

Is there any easy way to do this in Java? I'm aware of the BigInteger class which can convert the entire byte array to a binary String (then insert that way and convert back), but that seems inefficient.

Thanks in advance.

+1  A: 

You're going to want to use bitmasking and bitshifting. This bit of the Java documentation may be useful to you:

http://72.5.124.55/docs/books/tutorial/java/nutsandbolts/op3.html

To be precise, you're probably going to want to convert your byte array to an integer, create a variable for your lowest-order bits and copy them over, bitmask out (using an AND mask) those bits from your the original variable, bitshift the original variable, then bitmask back (using an OR mask) the low-order bits you preserved.

McWafflestix
I'm going to need some time to review this approach. :)
A: 

Check out the BitSet class. It can do what you need pretty trivially.

Gandalf
Converting a byte array to a BitSet and vice-versa is still a problem, correct? I would have to parse all the bits and add their values to a BitSet.
BitSets don't let you "insert" bits, it simply allows you to set them.It does let you iterate over the bits, so you could recreate a new BitSet from an old, and increment all of the bits past the insertion point. I doubt this is efficient, though.
Will Hartung
+6  A: 

The tricky bit is to shift the character where you actually want to insert the bit, because you only want to shift part of it. That can be done using a function like this:

public static char shift(char in, char n, char v)
{
    char lowMask = (1 << n) - 1;
    char highMask = 0xFF ^ lowMask;

    return (in & lowMask) | ((in & highMask) << 1) | ((v&1) << n);
}

After you've inserted the bit into the first character you'll have to shift the rest of the array as well. That can be done by simply shifting one bit to the right (<< 1) and setting the least significant bit (LSB) of the next character to the state of the most significant bit (MSB) in the last character.

Emil H
A: 

This function here would work on a single byte, you could convert to a unicode CHAR if you needed to do anything bigger:

static byte InsertBit(byte original, byte location)
        {
            byte highBits=original & ~(1<<location-1) ;
            byte lowBits = (1 << location - 1) & (original >> 1);

            return (1<< location) | highBits |lowBits;
        }
Erich