Операции с примитивни типове в Java. Аритметични операции

Нека да разберем един от подходите за въвеждане на данни от стандартния поток през клас java.util.Scanner... Нека направим това с примера на проста задача от много полезния сайт e-olimp.com

Задача

Въведете едно число от стандартния поток. Ако приемем, че това е положително двуцифрено цяло число, отпечатайте всяка цифра поотделно (разделена с интервал) в стандартния изходен поток. Редът на числата не трябва да се променя.

Тестове

В алгоритъма не се приемат конкретни случаи. Правим три теста - най-малкият брой от валидния диапазон, най-големият и някаква стойност от средата на диапазона.

вход Изход
10 1 0
99 9 9
54 5 4

Решение

Нека използваме класа java.util.Scanner,за въвеждане на данни в целочислен формат. И нека изчислим и двете му числа.

Показване на цифрите на двуцифрено цяло число

Java

клас Main (public static void main (String args) хвърля java.lang.Exception (java.util.Scanner i = new java.util.Scanner (System.in); int n = i.nextInt (); System.out). println (n / 10 + "" + n% 10);))

клас Основен (

public static void main (String args) хвърля java. език Изключение (

java. util. Скенер i = нова java. util. Скенер (системен вход);

int n = i. nextInt ();

Система. навън. println (n / 10 + "" + n% 10);

Обяснения

  1. Ние описваме променливата иТип java.util.Scannerи веднага му присвоете стойността на нов обект от този клас. Конструкторът създава обекта Скенер„Но от stdin. Тези. истава добавка към стандартния вход. Това ни позволява да четем цяло число, а не просто да го четем с метода Прочети() един байт наведнъж.
  2. Използване на метода nextInt() прочетете поредица от числа и я преобразувайте в цяло число. Съхраняваме числото в променливата n.
  3. н/ 10 - броят на десетките в числото. Десетките ще бъдат десет пъти по-малко от самото число. Извършва се целочислено деление - целочислено деление.
  4. н% 10 - изчисляване на остатъка от деление на десет - броя на единиците - най-дясната цифра на числото.
  5. н/ 10 + "" + н% 10 - вмъкване на един интервал между две цели числа. В този случай числата също се преобразуват в низово представяне и и трите низа се конкатенират - нарича се конкатенация на низове. Ето как операцията "+" работи с низови данни.

Ускорете I/O

С цялото удобство на този подход, той е доста бавен и понякога задачите не се изпълняват навреме. Можете значително да ускорите работата, като използвате StreamTokenizer и PrintWriter.
Това ще увеличи количеството код, но ще спести време.

Ускоряване на I/O

Java

импортирайте java.io. *; импортирайте java.util. *; клас Main (статичен StreamTokenizer in = нов StreamTokenizer (нов BufferedReader (нов InputStreamReader (System.in))); static PrintWriter out = нов PrintWriter (System.out); static int nextInt () хвърля IOException (in.nextToken (); return); (int) in.nval;) public static void main (String args) хвърля java.lang.Exception (int n = nextInt (); out.println (n / 10 + "" + n% 10); out.flush ( ;))

импортиране на java. io *;

импортиране на java. util. *;

клас Основен (

static StreamTokenizer in = нов StreamTokenizer (нов BufferedReader (нов InputStreamReader (System. in)));

static PrintWriter out = нов PrintWriter (System. out);

static int nextInt () хвърля IOException (


Учене за "Разработчик на игри" + работа

Java оператори

Езикът на Java използва обичайните + - * / аритметични оператори за означаване на събиране, изваждане, умножение и деление.

Операторът / обозначава целочислено деление, ако и двата му аргумента са цели числа. В противен случай този оператор обозначава деление с плаваща запетая. Остатъкът от деленето на цели числа (т.е. функцията mod) се обозначава със символа %.
Например 15/2 е 7, 15% 2 е 1 и 15. 0/2 е равно на 7. 5.

Обърнете внимание, че целочисленото деление на 0 предизвиква изключение, докато деленето на 0 на числата с плаваща запетая води до безкрайност или NaN.

Аритметичните оператори могат да се използват за инициализиране на променливи.

int n = 5;
int a = 2 *н; // Стойността на променливата a е 10.

Удобно е да се използват стенографски двоични аритметични оператори в операторите за присвояване.

Например операторът
х + = 4;
еквивалентно на оператор
х = х + 4;

(Съкратените оператори за присвояване се генерират чрез префикс на знак за аритметична операция, като * или%, преди знака =, като * = или% =.)

Една от посочените цели на езика Java е машинната независимост.

Изчисленията трябва да доведат до един и същ резултат, независимо коя виртуална машина ги изпълнява. За аритметиката с плаваща запетая това е изненадващо трудно. Двойният тип използва 64 бита за съхраняване на числови стойности, но някои процесори използват 80-битови регистри с плаваща запетая. Тези регистри осигуряват допълнителна прецизност в междинните етапи на изчисление. Нека вземем следния израз като пример:

двойно w = x * y / z;

Много процесори на Intel оценяват израза x * y и съхраняват този междинен резултат в 80-битов регистър, след което го разделят на стойността на z и закръглят отговора до 64 бита в самия край. Това може да подобри точността на изчисленията и да избегне преливания. Този резултат обаче може да бъде различен, ако 64-битов процесор се използва във всички изчисления.

Поради тази причина оригиналната спецификация на виртуалната машина на Java посочва, че всички междинни изчисления трябва да бъдат закръглени. Това разгневи компютърната общност. Не само закръглените изчисления могат да причинят преливания. Всъщност те са по-бавни от по-точните изчисления, тъй като операциите по закръгляване отнемат известно време. В резултат на това разработчиците на езика Java промениха мнението си, стремейки се да разрешат конфликта между оптимална производителност и отлична възпроизводимост на резултатите.

По подразбиране разработчиците на виртуални машини вече позволяват по-голяма точност в междинните изчисления. Въпреки това, методите, маркирани с ключовата дума strictfp, трябва да използват точни операции с плаваща запетая, за да осигурят възпроизводими резултати. Например основният метод може да бъде маркиран с ключови думи, както е показано по-долу:
публичен статичен strictfp void main (String args)

В този случай всички команди в основния метод ще изпълняват точни операции върху числата с плаваща запетая.

Подробностите за тези операции са тясно свързани с начина, по който работят процесорите на Intel. По подразбиране междинните резултати могат да използват разширения показател, но не и разширената мантиса. (Чиповете на Intel поддържат закръгляне на мантисата, без да се жертва производителността.) Следователно единствената разлика между изчислението по подразбиране и точното изчисление е, че прецизното изчисление може да прелива, докато изчислението по подразбиране не.

Ако погледът ви избледнее, докато четете тази бележка, не се притеснявайте. За повечето програмисти този въпрос е напълно ирелевантен. Препълвания с плаваща запетая не се случват в повечето случаи. В тази книга няма да използваме ключовата дума strictfp.

Оператори за увеличение и декремент

Програмистите, разбира се, знаят, че една от най-често срещаните операции с числови променливи е събирането или изваждането на единица. В езика Java, както и в езиците C и C ++, има оператори за увеличение и декремент: операторът x ++ добавя единица към текущата стойност на променливата x, а операторът x- изважда едно от нея.

Например кодът
int n = 12;
n ++;
прави стойността на променливата n равна на 13.

Тъй като тези оператори променят стойността на променлива, те не могат да бъдат приложени към самите числа. Например, операторът 4 ++ не е валиден.

Има два вида на тези оператори. По-горе е показана "postfix" формата на оператора, в която символите на оператора се поставят след операнда. Има и "префиксна" форма - ++ n.
И двата оператора увеличават стойността на променливата с едно. Разликата между двете се появява само когато тези оператори се използват в изразите. Префиксната форма на оператора за увеличение първо добавя единица към стойността на променлива, докато постфиксната форма използва старата стойност на тази променлива.

int m = 7;
int n = 7;
int a = 2 * ++ m; // Сега a е 16 и m е 8.
int b = 2 * n ++; // Сега b е 14 и n е 8.

(Тъй като операторът ++ даде името на езика C ++, това беше причината за първата шега за него. Недоброжелатели посочват, че дори името на този език съдържа грешка: „Наред с други неща , този език трябва да се нарича ++ C, защото искаме да използваме този език само след като го подобрим. ")

1. Основни аритметични операции

Следната таблица изброява основните аритметични операции, използвани в езика Java:

Нека разгледаме някои правила за работа с аритметични операции:

  • Изразите се оценяват отляво надясно, освен ако не се добавят скоби или някои операции имат предимство.
  • Операциите *, / и% имат предимство пред + и -.

Пример 1. Аритметични операции върху целочислени стойности

Например в този код променливите аи бще има различни значения:

Публичен клас BasicIntMath (обществен статичен void main (String args) (int a = 4 + 5 - 2 * 3; int b = 4 + (5 - 2) * 3; System.out.println ("a =" + a)) ; System.out.println ("b =" + b);))

Резултат от изпълнението:

A = 3 b = 13

  • Операцията за унарно изваждане променя знака на единствения си операнд.
  • Унарната операция за събиране просто връща стойността на своя операнд. По принцип не е необходимо, но е възможно.

Пример 2. Унарни операции за събиране и изваждане

публичен клас UnarySignOperation (public static void main (String args) (double a = -6; double b = +6; System.out.println (a); System.out.println (b);))
  • Когато операция на разделяне се извършва върху целочислен тип данни, резултатът няма да съдържа дробен компонент.

Пример 3. Деление на цели числа

публичен клас IntDivision (public static void main (String args) (int a = 16/5; System.out.println (a);))

Резултатът от стартирането на тази програма:

  • Операндите за аритметичните операции трябва да са от числов тип. Аритметичните операции не могат да се извършват върху булеви типове данни, но могат да се извършват върху типове данни charтъй като в Java този тип е по същество вариация на типа международен.

Пример 4. Аритметични операции върху тип променливи char

публичен клас BasicCharMath1 (public static void main (String args) (char c = "n"; System.out.println (c); System.out.println (c + 1); System.out.println (c / 5)) ;))

Резултат от изпълнението:

N 111 22

Пример 5. Аритметични операции върху тип променливи char

публичен клас BasicCharMath2 (public static void main (String args) (char c1 = "1"; char c2 = "\ u0031"; char c3 = 49; System.out.println (c1 + c2 + c3);))

Резултат от изпълнението:

    Оператор по модул - означава се с%. Този оператор връща остатъка от първото число, разделен на второто. При разделяне на цяло число резултатът също е цяло число.

Пример 6. Деление по модул

публичен клас DivisionByModule (public static void main (String args) (int a = 6% 5; double b = 6.2% 5.0; System.out.println (a); System.out.println (b);))

Резултат от изпълнението:

1 1.2000000000000002

2. Съставни аритметични операции със присвояване

Java има специални операции, които комбинират аритметиката с присвояването. Помислете за следния израз:

А = а + 4;

В Java тази операция може да бъде написана по следния начин:

А + = 4;

Композитните операции за присвояване не само ви позволяват да намалите количеството код, но също така ви позволяват да извършвате автоматично преобразуване, което не се извършва от конвенционалните операции.

Пример 5. Съставни аритметични операции за присвояване

публичен клас CompoundOperations (public static void main (String args) (int a = 1; int b = 2; int c = 3; a + = 3; b * = 2; c + = a * b; System.out.println (a); System.out.println (b); System.out.println (c);))

Повечето операции с примитивни типове се извършват не с помощта на методи, а с помощта на специални символи, наречени знак за операция.

Операция за присвояване

Присвояването на променлива стойността на константа, друга променлива или израз (променливи и/или константи, разделени със знаци за операция) се нарича операция за присвояванеи се обозначава със знака " = ", например: x = 3; y = x; z = x; В Java е разрешено повторното използване на операцията за присвояване в един израз, например: x1 = x2 = x3 = 0; Тази операция се изпълнява от дясно до вляво, тоест първо на променливата x3 се присвоява стойността 0, след това x2 се присвоява стойността на x3 (0) и накрая x1 се присвоява стойността на x2 (0). Знаците за операция, които използват числа като аргументи, попадат в две категории: унарни(унарни) токени за операции с един аргумент и двоичен(двоичен) с два аргумента.

Унарни операции

Следните унарни операции са дефинирани в Java:
  • унарно минус "-" - променя знака на число или израз на противоположен;
  • унарно плюс "+" - не извършва никакво действие върху число или израз;
  • побитово допълнение "~" (само за цели числа) - инвертира всички битове от числовото поле (променя 0 към 1 и 1 към 0);
  • инкремент "++" (само за цели числа) - увеличава стойността на променливата с 1;
  • декремент "-" (само за цели числа) - намалява стойността на променливата с 1.
Примери за унарни операции "+" и "-": int i = 3, j, k; j = - i; // j = -3 k = + i; // k = 3 Пример за операция за побитово допълнение: int a = 15; int b; b = ~ a; // b = -16 Числата a и b са int, т.е. са представени вътрешно като двоични знакови цели числа с дължина 32 бита, така че двоичното представяне на числата a и b ще изглежда така: a = 00000000 00000000 00000000 00001111 b = 111111111 111, вижте всички това от 111. нулевите битове в числото a са променени с тези в b, а тези в a са променени на нулеви битове. Десетичното представяне на b е –16. Знаците за операция за увеличаване и намаляване могат да бъдат поставени преди или след променливата. Тези опции са наречени съответно префикси постфиксчрез записване на тези операции. Знакът на оператора в префиксната нотация връща стойността на своя операнд следоценяване на израз. За постфиксна нотация, знакът за операция първовръща стойността на своя операнд и едва след това изчислява увеличението или декремента, например: int x = 1, y, z; y = ++ x; z = x ++; На променливата y ще бъде присвоена стойност 2, тъй като първо стойността на x ще бъде увеличена с 1, а след това резултатът ще бъде присвоен на променливата y. На променливата z ще бъде присвоена стойност 1, тъй като първо на променливата z ще бъде присвоена стойност, а след това стойността на x ще бъде увеличена с 1. И в двата случая новата стойност на x ще бъде 2. Трябва да се отбележи, че в Java, за разлика от C, операциите за намаляване и увеличение могат да се прилагат и към реални променливи (от типа float и double). Знаци за двоична операциясе разделят на операции с числов резултат и операции за сравнение, чийто резултат е булева стойност.

Аритметични двоични операции

Java дефинира следното аритметични двоични операции:
  • допълнение "+";
  • изваждане "-";
  • умножение " * ";
  • разделение "/";
  • изчисляване на остатъка от деленето на цели числа "%" (връща остатъка от разделянето на първото число на второто и резултатът ще има същия знак като дивидента), например резултатът от операция 5% 3 ще бъде 2 и резултатът от операцията (-7) % (- 4) ще бъде -3. В Java операцията може да се използва и за реални променливи (като float или double).
Примери за двоични аритметични операции: int x = 7, x1, x2, x3, x4, x5; x1 = x + 10; // x1 = 17 x2 = x - 8; // x2 = -1 x3 = x2 * x; // x3 = -7 x4 = x / 4; // x4 = 1 (при разделяне на цели числа // дробната част се изхвърля) x5 = x% 4 // x5 = 3 (остатък от делението// 7 на 4)

Побитови операции

  • Побитовите операции третират оригиналните числови стойности като битови полета и правят следното върху тях:
  • настройване на бита на и-та позиция на полето за резултат до 1, ако и двата бита са в и-ти позиции на операндите са равни на 1 или на 0, в противен случай - побитово И ("&");
  • настройване на бита на и-та позиция на полето за резултат до 1, ако има поне един бит и-та позиция на операндите е равна на 1, или на 0, в противен случай - побитово ИЛИ ("|");
  • настройване на бита на и-та позиция на полето за резултат до 1, ако битовете са в и-ти позиции на операндите не са равни една на друга, нито на 0, в противен случай - побитово изключително ИЛИ ("^");
  • ляво изместване на битовете на полето на първия операнд с броя битове, определени от втория операнд (знаковият бит на числото не се променя в този случай) - побитово изместване наляво, като се вземе предвид знакът "<< ";
  • изместване вдясно от битовете на полето на първия операнд с броя на битовете, определен от втория операнд (знакът на числото не се променя в този случай) - побитово изместване надясно, като се вземе предвид " >>" знак;
  • изместване вдясно от битовете на полето на първия операнд с броя на битовете, определен от втория операнд (знакът на числото също се измества в този случай) - побитово изместване надясно, без да се взема предвид " >>>" знак.
Примери за побитови операции:
  1. Побитово И

    int x = 112; int y = 94; int z; z = x & y; // z = 80: 00000000 00000000 00000000 01010000
  2. Побитово ИЛИ

    int x = 112; // x: 00000000 00000000 00000000 01110000 int y = 94; // y: 00000000 00000000 00000000 01011110 int z; z = x | y; // z = 126: 00000000 00000000 00000000 01111110
  3. Побитово изключително ИЛИ

    int x = 112; // x: 00000000 00000000 00000000 01110000 int y = 94; // y: 00000000 00000000 00000000 01011110 int z; z = x ^ y; // z = 46: 00000000 00000000 00000000 00101110
  4. Преместете наляво, като вземете предвид знака

    int x = 31, z; // x: 00000000 00000000 00000000 00011111 z = x<< 2 ; // z = 124: 00000000 00000000 00000000 01111100
  5. Преместете надясно, като вземете предвид знака

    int x = - 17, z; z = x >> 2; // z = -5: 11111111 11111111 11111111 11111011
  6. Преместване надясно, без да се съобразява със знака

    int x = - 17, z; // x: 11111111 11111111 11111111 11101111 z = x >>> 2; // z = 1073741819 // z: 00111111 11111111 11111111 11111011

Комбинирани операции

В Java за бинарни аритметични операции можете да използвате комбинирани(сложни) токени за операция: идентификатор операция = израз Това е еквивалентно на следната операция: идентификатор = идентификатор операция израз Примери:
  1. Изразът x + = b означава x = x + b.
  2. Изразът x - = b означава x = x - b.
  3. Изразът x * = b означава x = x * b.
  4. Изразът x / = b означава x = x / b.
  5. Изразът x% = b означава x = x% b.
  6. Изразът x & = b означава x = x & b.
  7. Изразът x | = b означава x = x | б.
  8. Изразът x ^ = b означава x = x ^ b.
  9. Израз x<<= b означает x = x << b .
  10. Изразът x >> = b означава x = x >> b.
  11. Изразът x >>> = b означава x = x >>> b.

Операции за сравнение

Java дефинира следните оператори за сравнение:
  • "==" (равно), "! =" (не е равно),
  • ">" (по-голямо от), "> =" (по-голямо или равно),
  • " < " (меньше) " <= " (меньше или равно)
имат два операнда и връщат булева стойност, съответстваща на резултата от сравнението ( фалшивоили вярно). Имайте предвид, че при сравняване на две стойности за равенство в Java, както в C и C ++, символите " == "(два знака за равенство без интервал), за разлика от оператора за присвояване, който използва" = ". Използването на символа" = "при сравняване на две стойности или причинява грешка при компилация, или дава неправилен резултат. Примери за операции за сравнение: boolean isEqual, isNonEqual, isGreater, isGreaterOrEqual, isLess, isLessOrEqual; int x1 = 5, x2 = 5, x3 = 3, x4 = 7; е равно = x1 == x2; // isEqual = true isNonEqual = x1! = x2; // isNonEqual = false isGreater = x1> x3; // isGreater = true // isGreaterOrEqual = true isGreaterOrEqual = x2> = x3; е по-малко = x3< x1; // isLess = true isLessOrEqual = x1 <= x3; // isLessOrEqual = false

Булеви операции

Булеви операциисе изпълняват върху булеви променливи и техният резултат също е стойност от тип булев... Следните булеви операции са дефинирани в Java:
  • отрицание "!" - замяна на false с true или обратно;
  • И операция "&" - резултатът е истинен само ако и двата операнда са верни, в противен случай резултатът е фалшив;
  • ИЛИ операция "|" - резултатът е верен само ако поне един от операндите е верен, в противен случай резултатът е фалшив.
  • XOR операция "^" - резултатът е истинен само ако операндите не са равни един на друг, в противен случай резултатът е фалшив.
Операторите "&", "|" и "^", както и съответните побитови оператори, могат да се използват в съставни оператори за присвояване: "& =", "| =" и "^ =" В допълнение, операциите " = са приложими за булеви операнди. = "(равно) и"! = "(не е равно). Както можете да видите от дефиницията на OR и AND, операцията OR се оценява на вярно, когато първият операнд е вярно, независимо от стойността на втория операнд, а операторът AND се оценява на false, когато първият операнд е false, независимо от стойността на втория операнд. Java дефинира още две булеви операции: втората версия на булевите И и ИЛИ, известни като логически операции на късо съединение: краткото И "&&" и краткото ИЛИ "||". Използвайки тези операции, вторият операнд изобщо няма да бъде оценен, което е полезно в случаите, когато правилната работа на десния операнд зависи от това дали левият операнд е вярно или невярно. Примери за булеви операции: boolean isInRange, isValid, isNotValid, isEqual, isNotEqual; int x = 8; isInRange = x> 0 && x< 5 ; // isInRange = false isValid = x >0 || x> 5; // isValid = true isNotValid =! е валиден; // isNotValid = false isEqual = isInRange == isValid; // isEqual = false // isNotEqual = true isNotEqual = isInRange! = isValid

Условна операция

Условна операция се записва във формата израз-1?Израз-2:израз-3. В този случай първо се оценява израз-1, който трябва да даде булева стойност и след това, ако израз-1 е вярно, израз-2 се оценява и връща като резултат от операцията, или (ако израз-1 е false ), а израз-3 се връща като резултат от операцията. Пример за условна операция: x = n> 1? 0:1; На променливата x ще бъде присвоена стойност 0, ако n> 1 (израз n> 1 се оценява на истина) или 1, ако n≤1 (израз n> 1 се оценява на false).

Старшинство на операциите

Операциите в изразите се извършват отляво надясно, но според техния приоритет. Така че операциите за умножение в израза y = x + z * 5; ще се изпълни преди операцията събиране, тъй като приоритетът на операцията умножение е по-висок от приоритета на операцията събиране. Приоритетите на операции (в ред на намаляващ приоритет) в Java са показани в таблица. 1.
Скобите увеличават приоритета на операциите, които са в тях. Така че, ако вмъкнете скоби в горния израз: y = (x + z) * 5; тогава първо ще се извърши операцията събиране, а след това операцията за умножение. Понякога скоби се използват просто, за да направят израза по-четим, например: (x> 1) && (x<= 5 ) ;

Преобразуване на типа и леене при извършване на операции

В изразите за присвояване и аритметичните изрази могат да се използват литерали, променливи и изрази от различни типове, например: double y; байт x; y = x + 5; Този пример добавя байтовата променлива x към литерала 5 (int) и присвоява резултата на двойната променлива y. В Java, както и в езика C, преобразуването на типове при оценката на изразите може да се извършва автоматично или с помощта на оператор за прехвърляне. Правилата за привеждане обаче са малко по-различни от тези на езика C и като цяло са по-строги, отколкото в езика C. При извършване на операция на присвояване преобразуването на типа става автоматично, ако разширяваща се трансформация(разширяващо преобразуване) и двата вида са съвместими... Разширяващите се трансформации са трансформации байт® къс® международен® дълго® плува® двойно... За разширяване на преобразувания, числовите типове, включително цяло число и плаваща запетая, са съвместими един с друг. Въпреки това, числовите типове не са съвместими с типовете char и boolean. Типовете char и boolean също не са съвместими един с друг. Java също така извършва автоматично преобразуване на тип, когато съхранява литерална целочислена константа (която е от тип int по подразбиране) в променливи от тип byte, short или long (обаче, ако литералът има стойност извън обхвата на валидните стойности за това тип, се показва съобщение за грешка: възможна загуба на точност). Ако преобразуването е стеснително преобразуване, тоест се извършва байт ¬ кратък ¬ ¬ ¬ знак ¬ дълго ¬ ¬ float ¬ double, тогава такова преобразуване може да доведе до загуба на прецизност или изкривяване на числото. Следователно, при стеснителни преобразувания, когато програмата се компилира, се показва диагностично съобщение за несъвместимост на типа и файловете на класа не се създават. Това съобщение също ще се показва, когато се опитвате да конвертирате изрази от тип байт или short в променлива от тип char. Ако все пак е необходимо да се извършат такива преобразувания, се използва операция cast, която има следния формат: ( тип преобразуване) смисъл, където тип преобразуванеопределя типа, в който даденото трябва да бъде преобразувано смисъл, например, в резултат на изпълнение на оператори: байт x = 71; символ символ = (char) x; символната променлива ще бъде настроена на "G". Ако стойност с плаваща запетая е присвоена на целочислен тип, тогава (ако стойността с плаваща запетая има дробна част), също се получава изрично преобразуване на тип съкращаване(отрязване) числа. И така, в резултат на изпълнението на оператора int x = (int) 77,85; променливата x ще бъде настроена на 77. Ако зададената стойност е извън обхвата преобразувания на типове , тогава резултатът от преобразуването ще бъде остатъкът от разделянето на стойността на модула на диапазона на присвоения тип (за числа от тип байт модулът на диапазона ще бъде 256, за кратко - 65536, за int - 4294967296 , и за дълго - 18446744073709551616). Например, в резултат на изявлението byte x = (byte) 514; променливата x ще бъде зададена на 2. При преобразуване на цели числа или реални числа в данни от тип char, преобразуването в знак става, ако оригиналното число е в диапазона от 0 до 127, в противен случай символът получава стойността "?". При извършване на аритметични и побитови преобразувания, всички байтове и къси стойности, както и char, се разширяват до int (докато числовата стойност на символния код се използва в изчисленията за char), тогава, ако поне един операнд е от тип long , типът на целочисления израз се разширява до long. Ако един от операндите е от тип float, тогава типът на пълния израз се разширява до float, а ако един от операндите е от тип double, тогава типът на резултата ще бъде double. Така че, ако променливите са декларирани байт a, c; кратко b; тогава в израза a + b * c - 15 L + 1.5F + 1.08 - 10; първо, преди да се изчисли a + b * c, стойностите на променливите ще бъдат разширени до int, след това, тъй като константа 15 е от тип long, резултатът от изчислението ще бъде увеличен до много преди изваждане. След това, тъй като литерал 1.5 е от тип float, резултатът от изчисляването на a + b * c - 15L ще бъде разширен до float, преди да бъде добавен към този литерал. Преди да извършите събирането с числото 1.08, резултатът от предишните изчисления ще бъде разширен до удвояване (тъй като реалните константи са от тип double по подразбиране) и накрая, преди извършване на последното добавяне, литерал 10 (по подразбиране int) ще бъде разширено до двойно. По този начин резултатът от оценката на израза ще бъде от тип double. Автоматичните разширения на тип (особено къси и байтове към int) могат да причинят лошо разпознати грешки по време на компилиране. Например в операторите: байт x = 30, y = 5; x = x + y; преди добавянето да бъде извършено, стойността на променливите x и y ще бъде разширена до int и след това ще се покаже съобщение за грешка при опит за присвояване на резултата от изчисление от тип int на променлива от тип байт. За да се избегне това е необходимо да се използва изрично преобразуване на тип във втория оператор: x = (байт) (x + y); Трябва да затворите израза x + y в скоби, тъй като приоритетът на преобразуването, оградено в скоби, е по-висок от приоритета на операцията за събиране. Между другото, ако напишете втория оператор като: x + = y; няма да има съобщение за грешка. Линк към първия

Унарните оператори са последвани от аритметичните оператори по приоритет. Тази група включва четирите най-често срещани оператора: събиране, изваждане, умножение, деление. И не само те. Има и модулен оператор, означен с%. Аритметичните оператори са разделени на две групи. Първата, по-приоритетна група съдържа *, /,%. Във втория, съответно, + и -.

Умножение и деление (* и /)

Операторите * и / извършват умножение и деление на всички примитивни числови типове и char. Деленето на нула води доАритметично изключение.

Сигурно се чудите защо ви говоря за умножение и деление, които знаете от първи клас. Въпреки това, в програмирането се справяме с някои ограничения, свързани с представянето на числа в компютър. Тези ограничения важат за всички цифрови формати, от байт до двоен. Но те са най-забележими за типа int.

Ако умножавате или разделите две числа, резултатът се изчислява с помощта на целочислена аритметика и се съхранява в int или long. Ако числата са много големи, тогава резултатът ще бъде по-голям от максималното число, което може да бъде представено в тези числа. Това означава, че резултатът няма да може да бъде правилно кодиран от компютъра и няма да има смисъл. Например, типът байт се използва за представяне на числа в диапазона от -128 до 127. Ако умножим 64 и 4, резултатът 256, който има девет знака в двоичен 100 000 000, се кодира като 0, тъй като байтът използва само 8 знака.

Помислете за разделяне. Ако делите в целочислена аритметика, резултатът трябва да е цяло число. Това означава, че дробната част ще бъде загубена. Например 7/4 ни дава 1,75, но в целочислена аритметика би било 1.

По този начин, ако имате работа със сложни изрази, можете да изберете последователност от умножения и деления. Но имайте предвид, че умножението може да доведе до препълване, а деление - на загуба на точност... Популярната мъдрост вярва, че извършването на първо умножение, а след това на деления, в повечето случаи дава правилния резултат. Нека разгледаме пример:

1.int a = 12345, b = 234567, c, d;
2.дълго e, f;
3.
4.c = a * b / b; // трябва да е равно на a = 12345
5.d = a / b * b; // също трябва да е равно на a = 12345
6. System.out.println („a is“ + a +
7. „\ nb е“ + b +
8. „\ nc е“ + c +
9. „\ nd е“ + d);
10.
11.e = (дълго) a * b / b;
12.f = (дълго) a / b * b;
13. System.out.println (
14. „\ ne е“ + e +
15. „\ nf е“ + f);

Резултатът от работата на този фрагмент ще даде следното:

А е 12345
b е 234567
c е -5965
d е 0
e е 12345
f е 0

Не се обърквайте от числовите стойности в този пример. Важното е, че когато направихме първо умножението, получихме препълване (c е -5965), когато го кодирахме, за да напишем int. Въпреки това можем да получим правилния резултат, ако го прекратим в по-дълъг тип, като long. И в двата случая прилагането на първо деление ще бъде пагубно за резултата, независимо от дължината на неговия вид.

Деление по модул%

Резултатът от делението по модул е ​​остатъкът от делението. Например, 7/4 е равно на 1 с остатъка от 3. Следователно, 7% 4 = 3. Обикновено операндите са от целочислен тип, но понякога операторът се прилага към числа с плаваща запетая. Трябва също да сте наясно с някои от характеристиките на този оператор, когато операндите са отрицателни.

За отрицателни или дробни операнди правилото е: извадете десния операнд от левия, докато последният е по-малък от първия.Примери:

17%5 = ? 17-5=12>5; 12-5=7>5; 7-5=2<5. Значит 17%5 = 2

21%7? 21-7=14>7; 14-7=7=7; 7-7=0<7. Значит 21%7 = 0

7.6%2.9? 7.6-2.9=4.7>2.9; 4.7-2.9=1.8<2.9. Значит 7.6%2.9=1.8

Забележка: знакът на резултата (положителен или отрицателен) се определя изцяло от знака на левия операнд, тоест от дивидента.

Когато се извършва деление по модул на дробни числа, същността на тази операция е да се извади делителя няколко пъти. Резултатът може да бъде и дробно число.

Едно просто правило за отрицателни операнди е да премахнете знака минус от операндите, да разделите по модул с положителни операнди и след това да добавите резултата с минус, ако левият операнд (дивидент) е отрицателен.

Делението по модул, подобно на нормалното деление, може да хвърли изключение ArithmeticException, ако делителят (десният операнд) е нула.