Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Операторы сдвига




Битовые операторы

Битовые операторы позволяют вам манипулировать индивидуальным битом в интегрированном примитивном типе данных. Битовые операторы вычисляются по Булевой алгебре над соответствующими битами двух аргументов для произведения результата.

Битовые операторы пришли из низкоуровневой ориентации C; вы будите часто напрямую манипулировать оборудованием и устанавливать биты в регистрах аппаратуры. Java изначально была разработана для встраивания в телевизор, так что низкоуровневая ориентация все еще чувствуется. Однако вы, вероятно, не будете часто использовать битовые операции.

Битовый оператор И (&) производит единицу в выходном бите, если оба входных бита были единицами; в противном случае результат - ноль. Битовый оператор ИЛИ (|) производит единицу в выходном бите, если один из входных бит - единица, и производит ноль, если оба бита - нули. Битовое ИСКЛЮЧАЮЩЕЕ ИЛИ, или XOR (^), производит единицу в выходном бите, если один или другой входной бит - единица, но не оба. Битовая операция НЕ (~, также называемый оператором дополнения) - это унарный оператор; он принимает только один аргумент. (Все остальные битовые операторы - бинарные.) Битовое НЕ на выходе производит бит, противоположных входящему — единицу, если входящий бит - ноль, и ноль, если входящий бит - единица.

Битовые операторы и логические операторы используют одинаковые символы, так что полезно иметь мнемоническую схему, которая поможет вам запомнить значения: так как биты “малы”, то используется только один символ в битовых операторах.

Битовые операторы можно комбинировать со знаком = для соединения операции и присвоения: &=, |= и ^= являются допустимыми. (Так как ~ - это унарный оператор, он не может комбинироваться со знаком =.)

Тип boolean трактуется как однобитное значение, так что это кое в чем отличается. Вы можете выполнять битовое И, ИЛИ и XOR, но вы не можете выполнять битовое НЕ (предположительно для предотвращения путаницы с логическим НЕ). Для булевских битовых операций имеется то же эффект, что и для логических операций, за исключением того, что они не подвержены короткому замыканию. Также, битовые операции на булевыми типами, включают логический оператор XOR, который не включен в список “логических” операторов. Вы предохранены от использования булевских типов в выражениях сдвига, которые описаны далее.

Операторы сдвига также манипулируют битами. Они могут использоваться исключительно с примитивными, целыми типами. Оператор сдвига влево (<<) производит действия над операндом, расположенным слева от оператора, сдвигая влево на число бит, указанное после оператора (вставляя нули в биты младшего порядка). Оператор сдвига вправо с учетом знака (>>) производит действия над операндом, расположенным слева от оператора, сдвигая вправо на число бит, указанное после оператора. Сдвиг вправо с учетом знака >> использует знаковое дополнение: если значение положительное в биты старшего порядка вставляются нули; если значение отрицательное, в старшие биты вставляются единицы. Java также добавлен беззнаковый сдвиг вправо >>>, который использует дополнение нулями: независимо от знака, в старшие биты вставляются нули. Этот оператор не существует ни в C, ни в C++.

Если вы сдвигаете char, byte или short, это переводится в int перед сдвигом, а результат будет типа int. Будут использоваться только пять младших бит с правой стороны. Это предохранит вас от сдвига на большее число бит, чем есть в int. Если вы работаете с long, в результате вы получите long. Будут использоваться только шесть младших бит с правой стороны, так что вы не сможете сдвинуть на большее число бит, чем есть в long.

Сдвиг может быть скомбинирован со знаком равенства (<<= или >>= или >>>=). lvalue заменяется на lvalue, сдвинутое на правое rvalue. Однако есть проблема с беззнаковым правым сдвигом, скомбинированным с присваиванием. Если вы используете byte или short, вы не получаете корректный результат. Вместо этого происходит преобразование к int и правый сдвиг, но затем происходит усечение, так как результат снова присваивается к той же переменной, так что в этих случаях вы получите -1. Приведенный пример демонстрирует это:

//: c03:URShift.java// Проверка беззнакового правого сдвига. public class URShift { public static void main(String[] args) { int i = -1; i >>>= 10; System.out.println(i); long l = -1; l >>>= 10; System.out.println(l); short s = -1; s >>>= 10; System.out.println(s); byte b = -1; b >>>= 10; System.out.println(b); b = -1; System.out.println(b>>>10); }} ///:~

В последней строке результирующее значение не присваивается назад переменной b, а сразу выводится на печать, поэтому мы видим правильное поведение.

Здесь мы видим пример, который демонстрирует использование всех операторов, использующих биты:

//: c03:BitManipulation.java// Использование битовых операторов.import java.util.*; public class BitManipulation { public static void main(String[] args) { Random rand = new Random(); int i = rand.nextInt(); int j = rand.nextInt(); pBinInt("-1", -1); pBinInt("+1", +1); int maxpos = 2147483647; pBinInt("maxpos", maxpos); int maxneg = -2147483648; pBinInt("maxneg", maxneg); pBinInt("i", i); pBinInt("~i", ~i); pBinInt("-i", -i); pBinInt("j", j); pBinInt("i & j", i & j); pBinInt("i | j", i | j); pBinInt("i ^ j", i ^ j); pBinInt("i << 5", i << 5); pBinInt("i >> 5", i >> 5); pBinInt("(~i) >> 5", (~i) >> 5); pBinInt("i >>> 5", i >>> 5); pBinInt("(~i) >>> 5", (~i) >>> 5); long l = rand.nextLong(); long m = rand.nextLong(); pBinLong("-1L", -1L); pBinLong("+1L", +1L); long ll = 9223372036854775807L; pBinLong("maxpos", ll); long lln = -9223372036854775808L; pBinLong("maxneg", lln); pBinLong("l", l); pBinLong("~l", ~l); pBinLong("-l", -l); pBinLong("m", m); pBinLong("l & m", l & m); pBinLong("l | m", l | m); pBinLong("l ^ m", l ^ m); pBinLong("l << 5", l << 5); pBinLong("l >> 5", l >> 5); pBinLong("(~l) >> 5", (~l) >> 5); pBinLong("l >>> 5", l >>> 5); pBinLong("(~l) >>> 5", (~l) >>> 5); } static void pBinInt(String s, int i) { System.out.println(s + ", int: " + i + ", binary: "); System.out.print(" "); for(int j = 31; j >=0; j--) if(((1 << j) & i)!= 0) System.out.print("1"); else System.out.print("0"); System.out.println(); } static void pBinLong(String s, long l) { System.out.println(s + ", long: " + l + ", binary: "); System.out.print(" "); for(int i = 63; i >=0; i--) if(((1L << i) & l)!= 0) System.out.print("1"); else System.out.print("0"); System.out.println(); }} ///:~

Два метода в конце: pBinInt() и pBinLong() получают int или long соответственно, и печатают их в бинарном формате вместе с описательной строкой. Вы можете пока проигнорировать их реализацию.

Вы обратите внимание на использование System.out.print() вместо System.out.println(). Метод print() не вызывает появление новой строки, так что это позволяет вам выводить строку по кусочкам.

Заодно здесь демонстрируется эффект для всех битовых операций для int и long, этот пример также показывает минимальное, максимальное, +1 и -1 значения для int и long, так что вы можете увидеть как они выглядят. Обратите внимание на битовое представление знака: 0 означает положительное число, 1 означает отрицательное. Вывод для части int выглядит так:

-1, int: -1, binary: 11111111111111111111111111111111+1, int: 1, binary: 00000000000000000000000000000001maxpos, int: 2147483647, binary: 01111111111111111111111111111111maxneg, int: -2147483648, binary: 10000000000000000000000000000000i, int: 59081716, binary: 00000011100001011000001111110100~i, int: -59081717, binary: 11111100011110100111110000001011-i, int: -59081716, binary: 11111100011110100111110000001100j, int: 198850956, binary: 00001011110110100011100110001100i & j, int: 58720644, binary: 00000011100000000000000110000100i | j, int: 199212028, binary: 00001011110111111011101111111100i ^ j, int: 140491384, binary: 00001000010111111011101001111000i << 5, int: 1890614912, binary: 01110000101100000111111010000000i >> 5, int: 1846303, binary: 00000000000111000010110000011111(~i) >> 5, int: -1846304, binary: 11111111111000111101001111100000i >>> 5, int: 1846303, binary: 00000000000111000010110000011111(~i) >>> 5, int: 132371424, binary: 00000111111000111101001111100000

Битовое представление чисел называется двоичным представлением.





Поделиться с друзьями:


Дата добавления: 2015-01-03; Просмотров: 405; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.01 сек.