- •Часть 1
- •1. Общие требования к выполнению лабораторных работ
- •2. Лабораторная работа №1. Выполнение простых программ в bluej
- •Часть 1. Создание и выполнение Java –программы.
- •Часть 2. Внесение изменений в программу.
- •Часть 3. Выполнение индивидуального задания.
- •3. Лабораторная работа № 2. Обработка данных простых типов. Работа с панелью кода bluej. Форматированный вывод
- •4. Лабораторная работа № 3. Обработка целочисленных данных.
- •5. Лабораторная работа № 4. Обработка двоичных векторов. Поразрядные логические операции.
5. Лабораторная работа № 4. Обработка двоичных векторов. Поразрядные логические операции.
5.1. Цель работы
Ознакомиться с принципами хранения и обработки двоичных векторов в Java, научиться использовать поразрядные логические операции.
5.2. Постановка задачи
1) Ознакомиться с принципами хранения и обработки двоичных векторов в Java.
2) Выполнить заданные поразрядные логические операции в окне кода.
3) Разработать и отладить программу, демонстрирующую выполнение поразрядных логических операций над двоичными векторами.
5.3. Внеаудиторная подготовка
Для подготовки к лабораторной работе следует ознакомиться с [1] (П.Ноутон, Г.Шилдт. Java 2, с.88-98).
5.4. Краткие теоретические сведения
Под двоичными векторами (двоичными кодами) понимают простые наборы битов − последовательности нулей и единиц, у которых все двоичные разряды равноправны (т.е. в отличие от чисел они не имеют знакового разряда) и над которыми можно выполнять поразрядные операции двоичной логики, такие как инверсия (НЕ), конъюнкция (И), дизъюнкция (ИЛИ), сложение по модулю два (исключающее ИЛИ), а также различные виды сдвигов.
В качестве примера можно привести регистр флагов прерываний процессора, состояние набора переключателей (включено-выключено) в какой-либо электрической схеме и.т.п.
Специальных беззнаковых типов данных для хранения двоичных векторов в Java не предусмотрено. Для указанной цели используются целые типы. Соответственно, для целых типов определены поразрядные логические операции. Знаковый разряд (левый разряд двоичного вектора) участвует в этих операциях наравне с другими разрядами. Это может вызвать интересные эффекты в программе. Например, значение переменной типа int, в которой хранится двоичный вектор, выводится с помощью метода println() как десятичное положительное число, а после выполнения операции инверсии этой переменной – как десятичное отрицательное число, хотя понятия знака для двоичного вектора не существует. Учитывая вышесказанное, рекомендуется использовать для получения строкового представления двоичного вектора, хранящегося в переменной целого типа метод toBinaryString(), который предоставляет соответствующий библиотечный класс-оболочка, например,
System.out.println(Integer.toBinaryString(x));.
Обобщая вышесказанное можно сделать вывод, что термин «двоичный вектор» характеризует не тип, а смысл данных. Для представления двоичных векторов используются целочисленные типы данных.
Обозначения поразрядных операций приведены в таблице 4.1. Таблица 4.2 демонстрирует правила выполнения логических поразрядных операций.
Таблица 4.1. – Обозначения поразрядных операций Java
Таблица 4.2 – Правила выполнения поразрядных логических операций.
Как видно из таблицы 4.1, в Java реализовано две операции сдвига вправо: так называемый арифметический сдвиг (с заполнением освобождающихся слева битов значением знакового разряда).Такой сдвиг (>>) может использован именно для числовых данных, например для организации экономичного деления числа на 2 или число, являющееся степенью двойки. Напомним, что сдвиг двоичного числа вправо на 1 двоичный разряд эквивалентен уменьшению этого числа в 2 раза.
Так называемый логический сдвиг вправо (>>> − сдвиг вправо с доопределением освобождающихся слева разрядов нулем) используется, как правило, для двоичных векторов.
Внимание! Правый беззнаковый сдвиг (>>>) на типах byte и short не работает. Это объясняется тем, что при выполнении операции короткие операнды расширяются до int (32-разрядных).
Логический сдвиг влево с доопределением нулями освобождающихся справа разрядов (<<) применяется как в работе с двоичными векторами, так и для экономичного умножения целых значений на 2 или число, являющееся степенью двойки. Здесь от программиста требуется внимание: он должен следить за тем, чтобы при выдвижении разрядов за разрядную сетку не изменился знак числа).
В операции сдвига участвуют два операнда. Первый операнд – сдвигаемое значение, второй операнд – константа сдвига (число разрядов, на которое производится сдвиг).
В данной работе требуется составить программу, которая меняет местами некоторые группы битов двоичного вектора, например, первый и второй байт двухбайтного вектора.
Пример. Дана двухбайтная последовательность нулей и единиц. Поменять местами первый и второй байты.
Дано: 10101010 11110000 (0xAAF0)
Нужно получить: 11110000 10101010 (0xF0AA)
А=10101010 11110000 (0xAAF0)
Алгоритм решения задачи (последовательность действий)
Выделить первый байт 10101010 00000000:
B=A & 0xFF00;.
2) Сдвинуть вправо на 8 бит 00000000 10101010:
B=B >> 8;.
3) Выделить второй байт 00000000 11110000:
D=A & 0x00FF;.
4) Сдвинуть влево на 8 бит 11110000 00000000:
D=D << 8;.
5) Объединить два полученных двоичных вектора.
D=D | B; 11110000 10101010.
Итак, для решения задачи, поставленной в лабораторной работе для конкретного варианта нужно 1) определить какие константы помогут выделить из исходного вектора нужные группы битов; 2) определить число разрядов, на которое нужно произвести сдвиг.
Заметим, что тип short не подходит для хранения двухбайтного логического вектора, рассмотренного в примере, по двум причинам:
В short не поместится 0xFF00 (не хватит одного бита, который отдан под знак). Максимальное значение для short – 0x7FFF (32767).
Операнды и результат при выполнении поразрядных логических операций все равно расширяются до int.
По указанным причинам выбираем рекомендуется выбирать для любых двоичных векторов, длина которых не больше 32 бит тип int.
В некоторых вариантах требуется запрограммировать операцию циклического сдвига. При циклическом сдвиге разряды, выдвигаемые за разрядную сетку не теряются, а доопределяют освобождающиеся разряды. Циклический сдвиг проиллюстрирован на рисунке 4.1. Поскольку такая операция в Java не предусмотрена, ее можно реализовать программно.
Рисунок
4.1 − Циклический сдвиг
5.5. Выполнение работы в лаборатории
1) В окне кода определите переменную x целого типа и присвойте ей произвольное значение в шестнадцатеричной системе счисления; выполните операции x>>3; x<<2; Осуществите вывод результата после выполнения каждой операции. Для вывода в терминал значения x в двоичной форме наберите в панели кода оператор:
System.out.println(Integer.toBinaryString(x));
Проанализируйте результат.
Повторите упражнение еще для двух произвольных значений х.
2) Упражнения для побитовых операций. Задайте произвольные значения двух int-переменных a и b. Выполните ~a, ~b, a^b, b^a, a|b, a&b, ~0, ~1, a&1. Фиксируйте результат каждой операции. Проверьте соответствие результатов правилам выполнения побитовых операций (таблица 4. 2).
3) Разработайте программу согласно варианту задания (таблица 4.3),
4) Обоснуйте выбор типа целочисленных переменных.
5) Проведите отладку программы и испытание на нескольких тестовых примерах.
5.6. Варианты заданий
В качестве индивидуального задания на лабораторную работу предлагается разработать программу, демонстрирующую выполнение поразрядных операций над двоичными векторами.
В программе задать двоичные вектора a и b.
Вывести на экран:
исходные значения a и b;
результаты выполнения операций ~a, a&b, a|b, a^b, a<<3, b>>3, a>>>5;
Результат операции над вектором a, заданной вариантом.
Для вывода двоичного представления вектора использовать метод System.out.println() в совокупности с методом Integer.toBinaryString(х), где x – аргумент типа int., например,
System.out.println("a & b = "+Integer.toBinaryString(a & b)); .
Проверить работу программы на нескольких тестовых примерах.
Варианты заданий представлены в таблице 5.3.
Таблица 5.3. – Варианты заданий
Номер варианта |
Количество байтов в двоичном векторе |
Операция |
1 |
1 |
Поменять местами тетрады |
2 |
2 |
Поменять местами вторую и третью тетрады |
3 |
2 |
Поменять местами первую и вторую тетрады |
4 |
2 |
Поменять местами третью и четвертую тетрады |
5 |
2 |
Поменять местами первую и третью тетрады |
6 |
2 |
Поменять местами вторую и четвертую тетрады |
7 |
3 |
Поменять местами первый и второй байт |
8 |
3 |
Поменять местами второй и третий байт |
9 |
3 |
Поменять местами первый и третий байт |
10 |
3 |
Поменять местами первую и шестую тетрады |
11 |
3 |
Поменять местами вторую и пятую тетрады |
12 |
3 |
Поменять местами третью и четвертую тетрады |
13 |
3 |
Поменять местами первую и третью тетрады |
14 |
3 |
Поменять местами вторую и четвертую тетрады |
15 |
3 |
Поменять местами третью и пятую тетрады |
16 |
3 |
Поменять местами первую и четвертую тетраду |
17 |
3 |
Поменять местами вторую и шестую тетрады |
18 |
3 |
Поменять местами третью и шестую тетрады |
19 |
4 |
Выполнить циклический сдвиг влево на 4 разряда |
20 |
4 |
Выполнить циклический сдвиг вправо на 4 разряда |
21 |
4 |
Выполнить циклический сдвиг влево на 8 разрядов |
22 |
4 |
Выполнить циклический сдвиг вправо на 8 разрядов |
23 |
4 |
Выполнить циклический сдвиг вправо на 16 разрядов |
24 |
4 |
Выполнить циклический сдвиг влево на 16 разрядов |
25 |
4 |
Поменять местами первый и третий байт |
5.7. Рекомендации по составлению отчета по лабораторной работе
В дополнение к общим требованиям к отчету, представленным в разделе 1, опишите по пунктам все исследования, которые вы провели в окне кода (п. 3.5.1) и сделанные вами выводы.
5.8. Контрольные вопросы.
1) Что такое двоичный вектор? Это тип или смысл данных (для Java)?
2) Какие типы данных в Java подходят для хранения двоичных векторов. Какой тип более предпочтителен и почему?
3) Какие поразрядные логические операции реализованы в Java. Как они обозначаются и выполняются?
4) Объясните правила, по которым можно вычислить результат для отдельного бита х, равного 0 или 1: ~x=1-x; 0^x=x; 1^x=~x; 0|x=x; 1|x=1; 0&x=0; 1&x=x.
5) Какие операции сдвига есть в Java. Для чего они применяются.
6) Что понимается под арифметическим, логическим, циклическим сдвигом?
7) Какой из перечисленных сдвигов не предусмотрен в Java? Как его реализовать.
8) Какие главные задачи решались при разработке программы перестановки групп битов в двоичном векторе?
9) Какой библиотечный метод удобно использовать для получения строкового (String) представления двоичного вектора.
БИБЛИОГРАФИЧЕСКИЙ СПИСОК
1. Ноутон П. Java 2: [пер. с англ.]/П.Ноутон, Г.Шилдт. – СПб.: БХВ-Петербург, 2007. – 1072 с.
2. Глушаков С. В Программирование на Java 2 : учеб. пособие для студ. вузов/ С. В. Глушаков. -2-е изд.-Харьков: Фолио, 2003.-544 с.
Приложение А
Пример оформления титульного листа отчета
Институт информационных технологий и управления
в технических системах
Кафедра информационных технологий и компьютерных систем
ОТЧЕТ
по лабораторной работе № 1
ВЫПОЛНЕНИЕ ПРОСТЫХ ПРОГРАММ В BLUEJ
по дисциплине «Программирование. Базовые процедуры обработки информации»
Выполнил студент группы ИВТб-11д
Орлов И.В.
Проверил доцент Петров И.И.
Севастополь
2015
