Java побитовая, вызывая странные результаты - PullRequest
0 голосов
/ 16 декабря 2018

Я пытаюсь использовать int для представления значения регистра.Мне нужны различные части числа (в его двоичной форме), чтобы установить состояние для линий управления и т. Д.

Мой код работает нормально, пока я не доберусь до номера 4096, в котором мои границы перестают себя вести.

мои границы определены следующим образом:

bit 1 to bit 2, bit 3- bit 6, 7-11, 12-13, 14-n

Я использую следующий код для преобразования битов границ в целые числа:

public int getNToKBits(int leftMostBit, int rightMostBit){
    int subBits = (((1 << leftMostBit) - 1) & (value >> (rightMostBit - 1)));
    return subBits;
}

, но когда я пытаюсь разбить число 4096 наэти границы я получаю следующим образом:

b: 00, 10, 10000, 0000, 00
d:  0,  2,    64,    0,  0 

-Я знаю, недостаточно битов, чтобы сделать 64 !!

то, что я ожидаю, это

b: 00, 10, 00000, 0000, 00
d:  0,  2,     0,    0,  0

Как и ожидалось, число меньше 4096. Возможно, это изменение в том, как java обрабатывает числа больше 4096?

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Для поля, которое вы определяете как 7: 11:

(((1 << leftMostBit) - 1) & (value >> (rightMostBit - 1)))
 ((1 << 11) - 1)                                           = 11111111111 binary
                            (4096 >> (7-1))                =     1000000 binary
 ((1 << 11) - 1)          & (4096 >> (7-1))                =     1000000 binary 

Это потому, что вы и с действительными (т.е. смещенными вправо) битами поля маска, вычисленная из крайнего левого числа бит (11),не количество битов в поле (что составляет 11-7 + 1 = 5).

Вам нужно либо сдвинуть, а затем замаскировать до размера (не самого левого бита):

( (value>>(rightmost-1)) & ((1<<(leftmost-rightmost+1))) )
// or equivalently 
( ((1<<(leftmost-rightmost+1))) & (value>>(rightmost-1)) )

Или же маскировать до самого левого бита перед shift:

( (value & ((1<<leftmost)-1)) >> (rightmost-1) )

И в последнем случае, если вы хотите (сможете) использовать знаковый бит (32 по вашему назначению), используйте >>> для правого сдвига вместо >>.

0 голосов
/ 16 декабря 2018

Вы можете определить что-то вроде этого:

public int subBits(int mask, int shift) {
    return (value & mask) >> shift;
}

Что будет использоваться следующим образом:

int[] bits = new int[5];

bits[0] = subBits(0b110000000000000, 13);
bits[1] = subBits(0b001100000000000, 11);
bits[2] = subBits(0b000011111000000, 6);
bits[3] = subBits(0b000000000111100, 2);
bits[4] = subBits(0b000000000000011, 0);
...