Сдвиг отрицательного значения BigInteger - Java

Я пытаюсь сдвинуть 7-байтовый массив вправо на 7 бит.

Для этого я использую метод shiftright BigInteger. Однако при сдвиге вправо для отрицательных BigInteger добавляется заполнение единицами или иногда удаляется ведущий бит.

Вот следующий фрагмент кода, выполняющий переключение:

byte[] vcwManD = decryptedVCW;
BigInteger bigIntD = new BigInteger(vcwManD);       // create big int array for shift
BigInteger shiftIntD= bigIntD.shiftRight(7);                // shift right 7 bits
vcwManD = shiftIntD.toByteArray();      

Для байтового массива E865037A9C6424 в двоичном формате:

11101000011001010000001101111010100111000110010000100100

При смещении я получаю D0CA06F538C8 в двоичном формате:

110100001100101000000110111101010011100011001000

Как видите, он сдвинулся на 7 бит вправо, однако старший бит был удален.

Другая проблема - отступ 1. Для байтового массива 90998951A37908 в двоичном формате

10010000100110011000100101010001101000110111100100001000

выдает FF213312A346F2 в двоичном формате:

11111111001000010011001100010010101000110100011011110010

На этот раз в начале было добавлено около 7 единиц.

Кто-нибудь знает, как решить эту проблему?

Большое спасибо Шив


person Seb    schedule 12.01.2016    source источник
comment
Вероятно, вам не следует использовать BigInteger для работы с двоичными данными.   -  person JimmyB    schedule 13.01.2016
comment
Кстати, целые числа со сдвигом вправо на 7 эквивалентны делению на 2 ^ 7 = 128.   -  person JimmyB    schedule 13.01.2016
comment
Из javadoc: беззнаковый оператор сдвига вправо (›››) опускается, так как эта операция не имеет смысла в сочетании с абстракцией бесконечного размера слова, предоставляемой этим классом.   -  person fabian    schedule 13.01.2016
comment
Я пробовал использовать long с масками и ››, однако я не знаю, возможно ли это смещение меньше, чем кратное 8 битам.   -  person Seb    schedule 13.01.2016
comment
Спасибо @HannoBinder, деление на 2 ^ 7 тоже подойдет.   -  person Seb    schedule 13.01.2016


Ответы (2)


Если вы выполняете битовые сдвиги, вы, вероятно, работаете с длинным беззнаковым значением, а не со значением со знаком. Итак, когда вы создаете свой BigInteger, используйте этот конструктор:

new BigInteger(1, vcwManD);

Таким образом, вы гарантированно получите положительное число, и вы сможете без всяких последствий менять его.

person Archimedes Trajano    schedule 12.01.2016

Отрицательные числа хранятся в памяти с использованием дополнения до двух. Это означает, что если число отрицательное, первый бит будет равен 1. Когда вы сдвигаете отрицательное число вправо, оно должно оставаться отрицательным, поэтому вновь введенные значения будут равны 1.

person Jason    schedule 12.01.2016
comment
Чтобы решить эту проблему, вам нужно будет использовать переменную без знака. - А что это за тип Java? ;-) - person JimmyB; 13.01.2016
comment
Возможно ли это в течение длительного времени? - person Seb; 13.01.2016
comment
@SHIV Да, поскольку у вас всего 7 байтов, а long - 8 байтов, вы можете поместить свои данные в неотрицательное значение long. - person JimmyB; 13.01.2016