Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Операции для целочисленных типов данных



Арифметические операции – (+ - * / %) – (сложение, вычитание умножение, деление нацело, вычисление остатка от деления). Результат этих операций – целочисленный.

Операции сравнения (или отношения) – (< > <= >= ==!=) – (меньше, больше, меньше или равно (не больше), больше или равно (не меньше), равно, не равно). Результат сравнения – булевское значение true (истина) или false (ложь), например, 2<3 имеет значение true, а 2>3 – значение false.

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

Арифметические операции с целочисленными данными выполняются точно, без округления. При выполнении целочисленного деления, дробная часть результата отбрасывается. В

Виду ограниченного диапазона (таблица 4.1), сложение и вычитание могут дать «переполнение» – результат, выходящий за границы диапазона. Переполнение выглядит как отрицательный результат при положительных слагаемых или как положительный результат при отрицательных слагаемых. Например, если к максимальному положительному int, равному 0x7FFF FFFF, прибавить 1, получится наименьшее целое отрицательное число 0x8000 0000. Если это число сложить с максимальным положительным (0x8000 0000 + 0x7FFF FFFF), получится число 0xFFFF FFFF (двоичное представление числа -1 в дополнительном коде), которое на единицу меньше нуля (легко проверить, прибавив к нему 1).

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

При вычислении значения выражения Java автоматически расширяет (повышает) тип каждого byte- или short-операнда и результата до int (т.к. результат сложения двух коротких операндов с одинаковыми знаками может не поместиться в короткий формат).

Это может вызывать плохо распознаваемые ошибки во время компиляции.

Например, казалось бы, благополучный код

byte b=50;

b=b*2;

вызовет ошибку компиляции «Возможна потеря точности – possible loss of precision», т.к. значение выражения b*2 имеет тип int, а целевая переменная b имеет тип byte. Такая же ошибка возникнет и при компиляции строки кода int i = 2L; (переменной типа int присваивается значение типа long).

Вообще, когда размер переменной слева меньше, чем размер результата справа, возникает ошибка «Возможна потеря точности – possible loss of precision».

Для преодоления этой трудности есть два пути:

1) числа длиной 1 байт хранить, например, в переменных типа int;

2) использовать явное преобразование типа значения в правой части оператора присваивания:

byte b=50;

b=(byte)(b*2);.

Следует отметить, что тип int – наиболее универсален и эффективен и должен быть использован для расчетов, индексации элементов массива или выполнения целочисленных операций.

Может показаться, что использование short или byte экономит память, но нет никакой гарантии, что Java не будет внутренне так или иначе расширять эти типы до int, Помните, что тип определяет поведение, а не размер. Единственное исключение – массивы, где тип byte гарантирует использование только одного байта на элемент массива, тип short будет забирать 2 байта, а int 4 байта [1].

4.5. Выполнение работы в лаборатории

1) Разработайте программу согласно варианту задания (таблица 4.2),

2) Обоснуйте выбор типа целочисленных переменных.

3) Проведите отладку программы и испытание на нескольких тестовых примерах.

4.6. Варианты заданий

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

В программе задать целочисленные переменные a, b, c. Вывести на экран в двоичной, шестнадцатеричной, восьмеричной и десятичной системах счисления значения а, b, c, а также результаты выполнения операций. -a, a+b, a-b, a*b, a/b, a%b, a++, b--. Например,

a+b=100000000(2)=100(16)= 400(8)=256 (10);.

Подобный вывод можно осуществить одним вызовом метода printf(). Для получения представления двоичного числа в виде строки (String) используйте библиотечную функцию Integer.toBinaryString(х), где x – аргумент типа int.

Сравнить с результатами ручных расчетов.

Варианты заданий представлены в таблице 4.2.

Таблица 4.2 – Варианты заданий

Номер варианта a b с
      (b-a)%a+56
      (a+b)/b-a+100%b
      a%b*2-b/4
      a/(b+20)-253%b
      (a+b)/(b+20)%20
      a/b%5+12*b
      a/b+(a%b)*2
      (a+2*b)/(a-5*b)%9
      a/16+b%16-10*a
      (a-b)/5+(b-500)%5*3
      (b-a+a/4+b*4)%10
      a*b-(a+b/2)%7
      (a%b-a/b)*20
      (a-b/2+b%10)*3
      a/b*(a-b)%15+25
      -(a/b+a%b)*5
      (b/a+b%a*3)/10
      (a*a-b)%25/2
      (a*a+b*b*b)/10%5
      ((a*a-b*b)+1024)%12/3
      ((b-a)/10)*((b-a)/10)%20
      (2*a+b/45)*3%14
      ((b-a)*2560%b)/12
      -2*(a%100+b%200)/5

4.7. Рекомендации по составлению отчета по лабораторной работе

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

4.8. Контрольные вопросы

1) Что такое литерал?

2) Как в программе задать целочисленные литералы в различных системах счисления?

3) Как получить представление двоичного целого числа в виде строки символов (String)?

4) Какие арифметические операции и операции сравнения допустимы для целочисленных типов?

5) Как выполняется операция целочисленного деления?

6) Как выполняется операция, обозначаемая символом %?

7) Что такое переменная? Как объявляется переменная целочисленного типа?

8) Как задать именованную константу целочисленного типа?

9) Какие ошибки могут возникать при компиляции оператора присваивания, использующего переменные и выражения различных целых типов? Приведите примеры.

10) Какой тип будет у результата выражения, в котором выполняются операции над переменными типа short и byte?

11) Какой тип предпочтительно выбирать для одиночных (не массивов) целочисленных переменных и почему?

12) Внутреннее представление чисел:

0 0100111,

1 1111101,

1 1111111,

0 0000000 0100111,

1 1111111 1111101,

1 1111111 1111111,

0 0000000 00000000 00000001 000011100,

1 1111111 11111111 11111111 101011010.

Запишите эти числа в десятичной, восьмеричной и шестнадцатеричной системах счисления. Какого они типа?

13. Назовите максимальное значение (в шестнадцатеричной системе счисления), которое можно записать в переменную типа byte, short, int и long.

14. Чему равны значения выражений 10<=3, 10!=3, 5>3+1? Какого они типа?

15. Фрагмент кода: int a=5; int b=3; f=a<b+1;. Какого типа переменная f и чему равно ее значение?

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)

Алгоритм решения задачи (последовательность действий)

1) Выделить первый байт 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 не подходит для хранения двухбайтного логического вектора, рассмотренного в примере, по двум причинам:

1) В short не поместится 0xFF00 (не хватит одного бита, который отдан под знак). Максимальное значение для short – 0x7FFF (32767).

2) Операнды и результат при выполнении поразрядных логических операций все равно расширяются до 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.

Вывести на экран:

1) исходные значения a и b;

2) результаты выполнения операций ~a, a&b, a|b, a^b, a<<3, b>>3, a>>>5;

3) Результат операции над вектором a, заданной вариантом.

Для вывода двоичного представления вектора использовать метод System.out.println() в совокупности с методом Integer.toBinaryString(х), где x – аргумент типа int., например,

System.out.println("a & b = "+Integer.toBinaryString(a & b));.

Проверить работу программы на нескольких тестовых примерах.

Варианты заданий представлены в таблице 5.3.

Таблица 5.3. – Варианты заданий

Номер варианта Количество байтов в двоичном векторе Операция
    Поменять местами тетрады
    Поменять местами вторую и третью тетрады
    Поменять местами первую и вторую тетрады
    Поменять местами третью и четвертую тетрады
    Поменять местами первую и третью тетрады
    Поменять местами вторую и четвертую тетрады
    Поменять местами первый и второй байт
    Поменять местами второй и третий байт
    Поменять местами первый и третий байт
    Поменять местами первую и шестую тетрады
    Поменять местами вторую и пятую тетрады
    Поменять местами третью и четвертую тетрады
    Поменять местами первую и третью тетрады
    Поменять местами вторую и четвертую тетрады
    Поменять местами третью и пятую тетрады
    Поменять местами первую и четвертую тетраду
    Поменять местами вторую и шестую тетрады
    Поменять местами третью и шестую тетрады
    Выполнить циклический сдвиг влево на 4 разряда
    Выполнить циклический сдвиг вправо на 4 разряда
    Выполнить циклический сдвиг влево на 8 разрядов
    Выполнить циклический сдвиг вправо на 8 разрядов
    Выполнить циклический сдвиг вправо на 16 разрядов
    Выполнить циклический сдвиг влево на 16 разрядов
    Поменять местами первый и третий байт

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-09-17; Прочитано: 1479 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.037 с)...