Арифметичні і побітові оператори мови Java 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Арифметичні і побітові оператори мови Java




До арифметичним операторам мови Java, які визначені для всіх числових типів, відносяться: + (додавання і унарний плюс), + = (додавання з привласненням), - (віднімання і унарний мінус), -= (віднімання з привласненням), * (множення), *= (множення з привласненням), / (ділення), / = (поділ з привласненням),% (залишок від ділення або ділення по модулю),% = (залишок від ділення з привласненням), + + (інкремент) і - (декремент).

Будь-який оператор з привласненням з точки зору одержуваного результату еквівалентний виконання відповідної операції з подальшим привласненням, але працює зазвичай швидше: @ = B еквівалентно а = @ B (тут символ @ означає будь-яку з бінарних арифметичних операцій).

Результат виконання операцій ділення і ділення за модулем (знаходження залишку) для цілочисельних операндів є цілим числом. Так, наприклад, 5/3 дорівнює 1.
Нарешті, операції інкремента і декремента відповідно збільшують і зменшують свій операнд на одиницю. Вони бувають префіксним і тоді зміна їх операнда відбувається до того, як виконуються інші дії у виразі, і постфіксні, коли зміна відбувається після обчислення виразу:

 

int i = 2, j = 3; // i = 2, j = 3 int k = i + j++; // k = 5, j = 4 int m = --i; // i = 1, m = 1


З величинами цілих типів можна виконувати додаткові дії. До побітових (або порозрядним) операторів мови Java належать такі: ~ (доповнення), & (побітове І), і = (побітове І з привласненням), | (побітове Або), | (побітове Або з привласненням), ^ (виключає Або), ^ = (виключає Або з привласненням), <<(зсув вліво), <<= (зрушення вліво з привласненням),>> (зсув вправо),>> = (зсув вправо з привласненням),>>> (зсув вправо з розмноженням нуля) і>>> = (зсув вправо з привласненням з розмноженням нуля).


Результати операцій побітового доповнення, Або, що виключає Або і І виходять шляхом виконання над кожним з бітів операнда (операндів) дій відповідно до таблиці 6.

Таблиця 6: Бітові операції

a b ~a a|b a^b a&b
           
           
           
           

 

Наприклад, 4 ~ 5 дорівнює 1 (бо виконавчі подання цих чисел є відповідно 100 і 101).
В операторів зсуву другий аргумент показує кількість розрядів, на яке треба здійснити зрушення в двійковому представленні першого операнда вл.іво (для <<) або вправо (для>> і >>>).

int i = 3, j = 100; // i = 3, j = 100 int k = i << 4; // k = 48 int m = j >> 2; // m = 25


Легко зрозуміти, що зрушення вліво на розрядів еквівалентний множенню на , а зрушення вправо - поділу на те ж число.

Задачи для самостійного рішення

 

Розділ II. Проектування програм з використанням мови програмування Java


Лекція 7.

Представлення інформації у комп'ютері

 

Будь-яка інформація (числова, текстова, звукова, графічна тощо) в комп'ютері представляється (кодується) у так званій двійковій формі. Як оперативна, так і зовнішня пам'ять, де і зберігається вся інформація, можуть розглядатися, як досить довгі послідовності з нулів і одиниць. Під зовнішньою пам'яттю маються на увазі такі носії інформації, як магнітні і оптичні диски, стрічки і т.п.

Одиницею виміру інформації є біт (BInary digiT) - саме таку кількість інформації міститься у відповіді на питання: нуль чи один? Більшими одиницями виміру інформації є байт, кілобайт (Kbyte), мегабайт (Mbyte), гігабайт (Gbyte) і терабайт (Tbyte). Один байт (byte) складається з восьми біт, а кожна наступна величина більша від попередньої в 1024 рази.

Байта достатньо для зберігання 256 різних значень, що дозволяє розміщувати в ньому будь-який з алфавітно-цифрових символів, якщо тільки ми можемо обмежитися мовами з невеликими алфавітами типу української чи англійської. Перші 128 символів (займають семеро молодших біт) стандартизовані за допомогою кодування ASCII (American Standart Code for Information Interchange). Гірше йде справа з кодуваннями українського тексту (символи українського алфавіту розташовані у другій половині таблиці з 256 символів) - їх кілька, а найбільш поширені з них зараз дві - Windows-1251 і KOI8-R.

Для кодування всіх можливих символів, використовуваних народами світу, одного байта мало - необхідно використовувати два послідовних (стандарт Unicode). Саме так і роблять при зберіганні символьних (char) значень в мові Java.

Корисно знати: що в книзі середнього розміру близько 300000 букв, легко підрахувати, що навіть не використовуючи ніяких ресурсів стиснення інформації, на жорсткому диску сучасного персонального комп'ютера ємністю в 20 гігабайт можна розмістити велику бібліотеку з майже 70000 книг.

Цілі числа

До цілочисельних типів в мовах програмування традиційно відносяться byte, short, int і long. Для збереження значень цих типів на будь-якому комп'ютері відводиться один, два, чотири і вісім байт відповідно. Застосовується представлення чисел в так званому двійковому додатковому коді.

Нагадаємо, що використовувана нами звичайна система числення є позиційною з основою 10. Це означає, що в ній всі натуральні числа представляються за допомогою десяти цифр (від нуля до дев'яти включно), а значення кожної з цифр числа залежить від позиції: перша права цифра означає число одиниць (), друга - десятків (), третя - - сотень () і так далі.

У р-ічній системі числення все точно так, як з числом 10 в попередньому абзаці лише потрібно всюди замінити 10 на р. Поряд з двійковою системою, в якій тільки дві цифри (0 і 1), в інформатиці часто застосовуються вісімкова з цифрами від нуля до 7 і шістнадцяткова. В останньому випадку в якості цифр від десяти до п'ятнадцяти використовуються букви від A до F відповідно.

При записі позитивних (додатніх) цілих чисел у системі числення з основою р (на комп'ютері p=2) всі їх множини виявляється складаються з елементів виду

де величини для всіх i з діапазону від до нуля - це цифри -значного числа з р-цяткової системи числення.

Перейдемо тепер до питання представлення негативних (відємних) чисел. Для визначеності розглянемо тип byte, в якому будь-яке число займає рівно вісім біт. Із запису в двійковій системі числення рівності легко знайти, який вигляд повинен мати невідоме нам поки двійкове подання xxxxxxxx числа :

xxxxxxxx + 00000001 = 00000000.

Ясно, що на місці символів xxxxxxxx повинно бути розташоване число 11111111. Правильним результатом при цьому, звичайно, слід було б вважати 100000000, а не 00000000, але ж ми маємо справу з типом byte і, так як результат зобов'язаний розміститися в байті, одиниця зникає.

Отже, число повинне кодуватися як 11111111. Подальше вже зовсім просто: для отримання -2 потрібно зменшити на одиницю, що дасть 11111110; число представляється як 11111101 і т.д.

Негативні числа завжди мають у своєму двійковому поданні одиницю в найстаршому розряді, який тому називають знаковим, а абсолютна величина кодованого числа виходить як двійкове доповнення інших біт (нулі потрібно замінити на одиниці і навпаки), збільшена на один.

Легко бачити, що при цьому найменшим негативним числом, яке належить типу byte, є число (двійкове подання 10000000), а найбільшим - число 127 (подання 01111111). Всі представимі (допустимі) числа (а їх 256) в даному випадку можуть бути отримані як перетин двох множин: множини всіх цілих чисел і відрізка .

Цікавим є наступне спостереження: якщо число 01111111 збільшити на одиницю, то вийде 10000000, що означає наступне:

Отже, множину елементів типу byte можна уявляти собі у вигляді згорнутого в кільце відрізка -128, 127 ]. Принципово нічого не міняється й для типів short, int і long - збільшується тільки довжина відрізка, який вирізається з дійсної прямої перед згортанням його в кільце. Мінімальні і максимальні представлені значення для кожного з цих типів в мовах програмування традиційно визначаються додатково. Наприклад в Java вони визначені, як значення констант MIN_VALUE і MAX_VALUE в класах java.lang.Short, java.lang.Integer і java.lang.Long відповідно.

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

Дійсні числа

Для представлення дійсних чисел в мовах програмування традиційно використовують змінні і константи типів float і double. Величини першого з них займають чотири байти, а другого - вісім.

На відміну від множини цілих чисел дійсні числа мають властивість щільності (повноти): між будь-якими двома різними числами завжди знайдеться відмінне від них третє. Зрозуміло, що будь-який із способів подання нескінченної кількості дійсних чисел за допомогою деякої обмеженої множини не дасть можливості зберегти властивість щільності.

Найбільш поширеним способом реалізації дійсних чисел на ЕОМ є використання чисел з плаваючою крапкою. У цьому випадку множина складається з елементів вигляду:

) , де цілі числа для всіх з діапазону від 1 до задовольняють співвідношення , а величина лежить в діапазоні від до U ().

У цьому випадку число є при цьому основою системи числення (найчастіше це 2), константа n задає точність представлення чисел (для типу double вона більше, ніж для float), а діапазон [ L,U ] визначає область значень експоненти (для типу double він також більше, ніж для float).

Число ) прийнято називати мантисою числа f з плаваючою точкою. Часто вимагають, щоб для всіх чисел f величина була ненульовою. Такі числа з плаваючою точкою називають нормалізованими.

У мові Java для кодування величин типів float і double також використовують числа з плаваючою крапкою. При цьому частину з наявної множини біт використовують для розміщення експоненти e, а інші біти - для розміщення мантиси.

Для того щоб добре зрозуміти, що ж представляє з себе множина нормалізованих чисел з плаваючою точкою, корисно зобразити його на числовій прямій для випадку невеликих n, L і U. Подібне завдання наведена в кінці параграфа. Зараз же нам буде достатньо досить якісного опису цієї множини.

Тому, що симетрична відносно початку координат, то можна розібратися тільки з невід'ємними числами. Нуль, звичайно ж, належить шуканій множині. Найближча до нуля наступна точка виходить при = L,

Це число для типів float і double визначено, як MIN_VALUE в класах java.lang.Float і java.lang.Double відповідно.

Правіше розташовується множина точок, наступних один за одним із кроком . Потім крок збільшується. Потім ще. І ще. При відстань між двома сусідніми точками множини і досягає . Найправіша точка множини виходить при і e =U. Для типів float і double це число визначено, як MAX_VALUE в класах java.lang.Float і java.lang.Double.

Окрім перерахованих (і симетричних їм негативних) значень у результаті виконання деяких операцій можуть вийти також такі особливі значення: плюс нескінченність (POSITIVE_INFINITY ), мінус нескінченність (NEGATIVE_INFINITY), мінус нуль і не число (NaN). Наприклад, при поділі одиниці на мінус нуль виходить мінус нескінченність.

Описані особливості множин машинних дійсних чисел призводять до того, що не для всіх його елементів вірні наступні співвідношення, які завжди справедливі для множини справжніх дійсних чисел

існує;
2 = x;
( 2) 2 = x;
•;


Наведемо кілька прикладів, що ілюструють ці особливості множини .

ЗАВДАННЯ 7.1. Знайдіть дійсне (типу double) число x таке, що x+1 = x, a (x ) / 2 x. Скористайтеся тим, що java. lang. Double визначає константу MAX_VALUE.

Розв’язок завдання представляє наступна програма:

 

public class DblMaxVal { public static void main(String[] args) { double x = Double.MAX_VALUE; double y = x + 1.0; if (x == y) { Xterm.print("Для числа "); Xterm.print("x = " + x, Xterm.Blue); Xterm.print(" величини x и (x+1) "); Xterm.print("рівні!\n", Xterm.Red); } y = 2.0 * x; double z = y / 2.0; if (x!= z) { Xterm.print("Для числа "); Xterm.print("x = " + x, Xterm.Blue); Xterm.print(" величини x и (2.0*x)/2.0 "); Xterm.print("різні\n", Xterm.Red); Xterm.print("і рівні відповідно"); Xterm.print(" " + x, Xterm.Red); Xterm.print(" і"); Xterm.print(" " + z + "\n", Xterm.Red); } }}

ЗАВДАННЯ 7.2. Знайдіть такі дійсні (типу doubie) числа a, b і c такі, що a+(b+c) (a +b) + c. Достатньо згадати, що точки множини знаходяться на числовій прямій нерівномірно.

Розв’язок завдання представляє наступна програма:

public class DblNoAssociative { public static void main(String[] args) { double x = 1.0e-16; double y = 1. + (x + x); double z = (1. + x) + x; if (y!= z) { Xterm.print("Для числа "); Xterm.print("x = " + x, Xterm.Blue); Xterm.print(" величини 1.+(x+x) и (1.+x)+x "); Xterm.print("різні\n", Xterm.Red); Xterm.print("і рівні відповідно"); Xterm.print(" " + y, Xterm.Red); Xterm.print("і"); Xterm.print(" " + z + "\n", Xterm.Red); } }}

Інколи навіть робота з не дуже малими або великими за абсолютною величиною числами може призвести до незвичайних результатів. Поглянемо на задачу про розв’язок квадратного рівняння.

ЗАВДАННЯ 7.3. Напишіть програму, яка вводить дійсні коефіцієнти a, b і c квадратного рівняння з позитивним дискримінантом, що знаходить обидва корені цього рівняння.

 

Ось найпростіше розв’язання цієї задачі, яке може бути написане будь-ким, хто має мінімальні знання мови Java.


public class SquareEquation {

public static void main(String[] args) throws Exception { double a = Xterm.inputDouble("Введіть число a -> "); double b = Xterm.inputDouble("Введіть число b -> "); double c = Xterm.inputDouble("Введіть число c -> "); if (a == 0.) { Xterm.println("Рівняння не квадратне", Xterm.Red); System.exit(0); } if (b*b - 4.*a*c <= 0.) { Xterm.println("Дискримінант непозитивний", Xterm.Red); return; } double x1 = (-b - Math.sqrt(b*b - 4.*a*c)) / (2.*a); double x2 = (-b + Math.sqrt(b*b - 4.*a*c)) / (2.*a); Xterm.println("Коріння рівняння:"); Xterm.println("x1 = " + x1, Xterm.Blue); Xterm.println("x2 = " + x2, Xterm.Blue);

Для визначення квадратного кореня тут використовується метод sqrt класу Math. Виклик методу System.exit і застосування оператора return, які в тілі методу main майже еквівалентні і приводять до негайного завершення виконання програми, що дозволяє обійтися без гілки else оператора if-else. Інша частина програми коментарів не потребує.


Спробуйте, однак, виконати цю програму при = 0.2E-16 і В = С = 1,0 - перший корінь рівняння x1 виявиться рівним-5.0E16, а другий x2 - нулю.


Якщо підставити ці значення у вираз + bx + c, то і для x1 x2 і для його значення виявиться рівним одиниці, а не нулю. Подібна помилка для першого, досить великого за величиною кореня, видається цілком природною, але ось погоджуватися з тим, що нуль є коренем даного рівняння, зовсім не хочеться. Цій проблемі присвячена одна з наведених нижче задач.



Поделиться:


Последнее изменение этой страницы: 2016-09-20; просмотров: 394; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.144.160.219 (0.035 с.)