views:

197

answers:

2

I am having trouble understanding what is happening in the two lines with the 0xFF7F and the one below it. There is a link here that explains it to some degree. http://www.herongyang.com/java/Bit-String-Set-Bit-to-Byte-Array.html I don't know if 0xFF7F>>posBit) & oldByte) & 0x00FF are supposed to be 3 values 'AND'ed together or how this is supposed to be read. If anyone can clarify what is happening here a little better, I would greatly appreciate it.

private static void setBit(byte[] data,
                               final int pos,
                               final int val) {
        int posByte = pos/8;
        int posBit = pos%8;
        byte oldByte = data[posByte];
        oldByte = (byte) (((0xFF7F>>posBit) & oldByte) & 0x00FF);
        byte newByte = (byte) ((val<<(8-(posBit+1))) | oldByte);
        data[posByte] = newByte;
    }

passed into this method as parameters from a selectBits method was setBit(out,i,val); out = is byte[] out = new byte[numOfBytes]; (numOfBytes can be 7 in this situation) i = which is number [57], the original number from the PC1 int array holding the 56-integers. val = which is the bit taken from the byte array from the getBit() method.

A: 

First of all 0xFF7F is 1111 1111 0111 1111. This is shifted right by an amount of bits calculated from the bit you pass as a parameter (so the one you want to set).

If you specify third bit posBit = 3 % 8 = 3 so

0xFF7F 1111 1111 0111 1111
>> 3   0001 1111 1110 1111

this value is then ANDed with the original byte you are modifying, the result is that every bit is kept equal to oldBit original bit except the one that is anded with the 0 bit, suppose you have for example oldByte == 0111 1010, you'll obtain:

    0111 1010
&   1110 1111
-------------
    0110 1010

Then the value is anded with 0xFF just to discard any bit that doesn't fit a byte (because it's at least the ninth bit) before doing the cast.

Jack
What is the significance of the hex numbers though? Why was 0xFF7F and 0x00FF chosen in this case?
somewhat_confused
They are _masks_, they are used with AND operator to select just some bits. In the first case 0xFF7F is used because you want to set a specified bit so you have all 1s except the one you want to work with (that is shifted according to __pos__). While 0x00FF is used to select just the lowest byte of a pair of bytes, since it selects just the lower 8 bits.
Jack
A: 

A better way to write this would be:

private static void setBit(byte[] data, int index, boolean value)
{
    final int byteIndex = index / 8;
    final int bitIndex = 7 - (index % 8);

    final byte mask = (byte) (1 << bitIndex);
    final byte valueBit = value ? mask : 0;

    data[byteIndex] = (byte) ((data[byteIndex] & ~mask) | valueBit);
}
starblue