Как работает bitshifting в Java?
у меня есть такое заявление:
предположим битовое значение byte
x
is 00101011. каков результатx>>2
?
Как я могу запрограммировать его и может кто-нибудь объяснить мне, что делать?
10 ответов:
во-первых, вы можете не сдвиг
byte
в Java, вы можете только изменитьint
илиlong
. Так чтоbyte
сначала пройдет продвижение, например
00101011
->00000000000000000000000000101011
или
11010100
->11111111111111111111111111010100
теперь
x >> N
означает (если вы рассматриваете его как строку двоичных цифр):
- самые правые N битов отбрасываются
- самый левый бит реплицируется столько раз, сколько необходимо дополнить результат до исходного размера (32 или 64 бит), например
00000000000000000000000000101011 >> 2
->00000000000000000000000000001010
11111111111111111111111111010100 >> 2
->11111111111111111111111111110101
двоичный 32 бит для
00101011
и
00000000 00000000 00000000 00101011
и в результате:00000000 00000000 00000000 00101011 >> 2(times) \ \ 00000000 00000000 00000000 00001010
сдвигает биты 43 влево на расстояние 2; заполняет самый высокий (знак) бит с левой стороны.
результат 00001010 с десятичным значением 10.
00001010 8+2 = 10
когда вы сдвигаете вправо 2 бита, вы отбрасываете 2 наименее значимых бита. Итак:
x = 00101011 x >> 2 // now (notice the 2 new 0's on the left of the byte) x = 00001010
это по сути то же самое, что деление int на 2, 2 раза.
В Java
byte b = (byte) 16; b = b >> 2; // prints 4 System.out.println(b);
эти примеры охватывают три типа сдвигов, применяемых как к положительному, так и к отрицательному числу:
// Signed left shift on 626348975 00100101010101010101001110101111 is 626348975 01001010101010101010011101011110 is 1252697950 after << 1 10010101010101010100111010111100 is -1789571396 after << 2 00101010101010101001110101111000 is 715824504 after << 3 // Signed left shift on -552270512 11011111000101010000010101010000 is -552270512 10111110001010100000101010100000 is -1104541024 after << 1 01111100010101000001010101000000 is 2085885248 after << 2 11111000101010000010101010000000 is -123196800 after << 3 // Signed right shift on 626348975 00100101010101010101001110101111 is 626348975 00010010101010101010100111010111 is 313174487 after >> 1 00001001010101010101010011101011 is 156587243 after >> 2 00000100101010101010101001110101 is 78293621 after >> 3 // Signed right shift on -552270512 11011111000101010000010101010000 is -552270512 11101111100010101000001010101000 is -276135256 after >> 1 11110111110001010100000101010100 is -138067628 after >> 2 11111011111000101010000010101010 is -69033814 after >> 3 // Unsigned right shift on 626348975 00100101010101010101001110101111 is 626348975 00010010101010101010100111010111 is 313174487 after >>> 1 00001001010101010101010011101011 is 156587243 after >>> 2 00000100101010101010101001110101 is 78293621 after >>> 3 // Unsigned right shift on -552270512 11011111000101010000010101010000 is -552270512 01101111100010101000001010101000 is 1871348392 after >>> 1 00110111110001010100000101010100 is 935674196 after >>> 2 00011011111000101010000010101010 is 467837098 after >>> 3
>>
- арифметический оператор сдвига вправо. Все биты первого операнда сдвигаются на количество мест, указанных во втором операнде. Самые левые биты в результате имеют то же значение, что и самый левый бит в исходном числе. (Это так, что отрицательные числа остаются отрицательными.)вот ваш конкретный случай:
00101011 001010 <-- Shifted twice to the right (rightmost bits dropped) 00001010 <-- Leftmost bits filled with 0s (to match leftmost bit in original number)
public class Shift { public static void main(String[] args) { Byte b = Byte.parseByte("00101011",2); System.out.println(b); byte val = b.byteValue(); Byte shifted = new Byte((byte) (val >> 2)); System.out.println(shifted); // often overloked are the methods of Integer int i = Integer.parseInt("00101011",2); System.out.println( Integer.toBinaryString(i)); i >>= 2; System.out.println( Integer.toBinaryString(i)); } }
выход:
43 10 101011 1010
вы не можете писать двоичные литералы как
00101011
в Java, так что вы можете написать его в шестнадцатеричном виде вместо:byte x = 0x2b;
чтобы вычислить результат
x >> 2
вы можете просто написать именно это и распечатать результат.System.out.println(x >> 2);
вы можете использовать, например, этот API, если вы хотите увидеть представление bitString ваших чисел. Uncommons Math
пример (в jruby)
bitString = org.uncommons.maths.binary.BitString.new(java.math.BigInteger.new("12").toString(2)) bitString.setBit(1, true) bitString.toNumber => 14
edit: изменена ссылка api и добавлен небольшой пример