Студопедия  
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

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

Читайте также:
  1. Арифметические операторы и операторы присваивания
  2. Е. Операторы
  3. Команды сдвига
  4. Лихие 90-е. Операторы и их опера
  5. Математические операторы
  6. МОДАЛЬНЫЕ ОПЕРАТОРЫ ВОЗМОЖНОСТИ
  7. МОДАЛЬНЫЕ ОПЕРАТОРЫ НЕОБХОДИМОСТИ
  8. Операторы
  9. Операторы
  10. Операторы прерывания

Операторы сдвига также манипулируют битами. Они могут использоваться исключительно с примитивными, целыми типами. Оператор сдвига влево (<<) производит действия над операндом, расположенным слева от оператора, сдвигая влево на число бит, указанное после оператора (вставляя нули в биты младшего порядка). Оператор сдвига вправо с учетом знака (>>) производит действия над операндом, расположенным слева от оператора, сдвигая вправо на число бит, указанное после оператора. Сдвиг вправо с учетом знака >> использует знаковое дополнение: если значение положительное в биты старшего порядка вставляются нули; если значение отрицательное, в старшие биты вставляются единицы. 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-09-11; просмотров: 23 | Поможем написать вашу работу | Нарушение авторских прав

Фаза 5: Эволюция | Первичное написание тестов | Общие ошибки дизайна | Где живет хранилище | Список аргументов | Ключевое слово static | Ваша первая Java программа | Вставка HTML | Упражнения | Присвоение |


lektsii.net - Лекции.Нет - 2014-2024 год. (0.006 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав