Операция взятия остатка от деления в Java
Я уже однажды расписывал операции в Java. В этой статье я акцентрирую внимание на операцию взятия остатка от деления, так как её работа отличается в различных языках программирования и иногда порождает недопонимание.
Операция взятия остатка % в Java работает не только с целыми числами, но и с числами с плавающей точкой.
Для целых чисел операция взятия остатка работает по такому принципу, что результат операции будет таким, что будет выполняться равенство:
Это равенство действует даже в том случае, если левый операнд будет наименьшим отрицательным числом для своего типа, а операнд в правой части будет равен -1 (тогда результатом будет 0).
Результатом операции взятия остатка для целых чисел в Java может быть отрицательное число только в том случае, если левый операнд будет отрицательным числом, а также результат может быть положительным только в том случае, если операнд в левой части будет положительным числом.
Если в правой части операции взятия остатка для целочисленных операндов в Java стоит 0, то результатом будет ArithmeticException .
Примеры работы операции взятия остатка для целочисленных операндов (выполнено в JShell):
Как я уже говорил, в Java операция взятия остатка % работает и с числами с плавающей точкой ( float и double ). Согласно спецификации языка Java операция взятия остатка для чисел с плавающей точкой работает не так, как это принято в IEEE 754, но если очень нужно то можно использовать метод Math . IEEEremainder .
В Java операция взятия остатка % работает согласно следующим правилам:
- Если один из операндов равен NaN, то результат операции будет NaN.
- Если результат не NaN, то знаком результата будет знак операнда в левой части.
- Если операнд в левой части Infinity, или операнд в правой части равен нулю, или выполняются оба условия, то результат будет равен операнду в левой части.
- Если операнд в левой части конечен, а операнд в правой части Infinity, то результат будет равен операнду в левой части.
- Если операнд в левой части равен нулю, а операнд в правой части конечен, то результат будет равен операнду в левой части.
- Во всех остальных случаях результат r взятия остатка от операнда n при делении на d определяется по математической формуле r = n — (d × q), где q будет целым числом, которое отрицательно только в случае, если n / d отрицательно, и положительно, если n / d положительно, и его размер максимально возможный, но не превышающий отношение n и d. Пример: 0,5 ÷ 0,3 = 1,6, тогда q будет положительным, так как 1,6 положительно, а наибольший размер, не превышающий 1,6 будет 1, то q = 1, а значит r = 0,5 — (0,3 × 1) = 0,2.
Операция взятия остатка для чисел с плавающей точкой никогда не приводит к возникновению Exception-ов.
Примеры операции взятия остатка для чисел с плавающей точкой:
Операции над переменными типа int
— Приветствую, Амиго! Сегодня мы с тобой будем разбираться с переменными типа int .
— Ты, как любой начинающий программист, пребываешь в своих иллюзиях. Ты что-то о них знаешь. Впрочем, ладно. Для начала давай разберёмся с вычислением целочисленных выражений. Ты ещё не забыл, как выглядит сокращённая запись создания и инициализации переменной?
— Всё верно. И каким может быть это самое значение в правой части от оператора присваивания (знака равенства)?
— Именно. А точнее — комбинация чисел, переменных и знаков + , — , * , / .
— Также можно использовать скобки ( ) . Главное, чтобы в результате получилось целое число.
— Кстати, в Java, как и в математике, сначала вычисляются выражения внутри скобок, а затем — вовне. Если вдруг забыл, напомню, умножение и деление имеют равный приоритет, и он выше, чем у сложения и вычитания.
— А можно ли использовать в выражении переменные?
— Отличный вопрос, Амиго. Можно. Вот пример:
int a = 1; int b = 2; int c = a * b + 2;
— Более того, одна и та же переменная может одновременно быть слева и справа от оператора присваивания :
int x = 5; x = x + 1; x = x + 1; x = x + 1; x = x + 1; x = x + 1;
— Это несколько сбивает с толку.
— С новичками так часто бывает. Не волнуйся — привыкнешь. Просто в языке Java символ = – это не обозначение равенства , а команда, которая в переменную слева от знака = заносит вычисленное значение выражения справа от знака = .
— Да. Поэтому не бойся записей вроде x = x + 1 . Ты просто заносишь в ячейку новое значение переменной x . Скажу больше: эту операцию ты будешь делать постоянно.
2. Деление целых чисел
— Амиго, ты умеешь делить целые числа друг на друга?
— Естественно! Я заканчивал младшую школу.
— В школьной арифметике так и есть. А вот в Java при делении одного целого числа на другое целое число всегда получается целое число. Остаток от деления при этом отбрасывается. Или же можно сказать, что результат деления всегда округляется до целого в меньшую сторону.
3. Остаток от деления целых чисел
— Кроме сложения, вычитания, умножения и деления для целых чисел в Java есть еще оператор «остаток от деления». Используется для этого символ процент – % . Это именно остаток от деления целого числа на целое, а не дробная часть.
— Не совсем понял, как считается остаток.
— Говоришь же, учился в младшей школе. Так уж и быть, напомню: допустим, тебе нужно разделить число 19 на 3 .
— Ага. Это понятно. А если делимое меньше делителя?
— Всё, теперь ясно. А зачем вообще этот оператор нужен?
— На самом деле это очень полезный оператор, и используется он довольно часто. Например, чтобы узнать, четное число или нет, достаточно поделить его на 2 и полученный остаток сравнить с нулем. Если остаток от деления равен нулю, число четное, если равен единице — нечетное.
— Выглядит эта проверка так:
Где, как вы уже догадались, a % 2 – получение остатка от деления на 2 (т.е. 0 или 1 ), а == используется для сравнения с нулем.
4. Инкремент и декремент
— В программировании очень часто приходится увеличивать или уменьшать переменную на единицу.
— Ну да. x = x + 1 . Видишь, я запомнил!
— Ты, конечно, молодец, но поскольку операция увеличения именно на единицу используется чрезвычайно часто, для неё в Java выделили специальные команды:
— Оператор инкремент (увеличение на единицу) выглядит так:
— Эта команда делает то же самое, что и команда a = a + 1 ; – увеличивает переменную a на единицу.
— Рад, что тебе нравится. Помимо инкремента есть ещё оператор декремент . Он выглядит так:
— Догадаешься, что он делает?
— Видимо, уменьшает на единицу!
— Всё правильно! Эта команда делает то же самое, что и команда a = a — 1 ; – уменьшает переменную a на единицу.
Деление по модулю в Java
Ещё со школы мы знакомы с таким понятием как обычное деление:
С этим все понятно. А что же это за «зверь» такой, деление по модулю ? И звучит то так угрожающе. А на самом деле всё очень и очень просто. Давайте разбираться.
Что Вам нужно понимать:
Как работает оператор сложения, вычитания и т.д. наверняка Вы уже знаете. А вот за что отвечает деление по модулю поймёте буквально через пару минут. Немного терпения.
- Деление по модулю обозначается вот таким знаком: %
- Деление по модулю иногда называют mod. То есть если увидите название mod, знайте, речь идет об операторе деление по модулю.
- В чём суть оператора? Деление по модулю даёт остаток от деления.
Давайте посмотрим на примерах как это работает.
Пример №1
Необходимо разделить 9 на 4, используя:
Логику работы оператора деления по модулю Вы уже поняли. Самое время попробовать запустить пример на своём компьютере:
Если Вы запустите этот код на своём компьютере, то в консоль будет выведено такое число:
Пример №2
Необходимо разделить 17 на 5, используя:
И пробуем теперь запустить программу на компьютере:
Если Вы запустите этот код на своём компьютере, то в консоль будет выведено такое число:
Пример №3
Необходимо разделить 21 на 7, используя:
И пробуем теперь запустить программу на компьютере:
Если Вы запустите этот код на своём компьютере, то в консоль будет выведено такое число:
Пример №4
Необходимо разделить 7.6 на 2.9, используя:
И пробуем теперь запустить программу на компьютере:
Если Вы запустите этот код на своём компьютере, то в консоль будет выведено число, близкое к 1.8. Например, Вы можете увидеть какое-то такое число: 1.7999999999999998. Из-за определённых особенностей Java, которые мы будем с Вами рассматривать позже в других статьях, на разных компьютерах число будет немного отличаться. Но оно будет близкое по значению к 1.8
Итак, как Вы уже поняли, оператор деления по модулю вычисляет остаток от деления.
- Применяется к таким типам переменных:
- Byte, short, Int, long – целочисленный тип переменных
- Float, Double – числа с плавающей точкой
- Отрицательные и положительные числа
Есть небольшой нюанс при использовании оператора деления по модулю с отрицательными и положительными числами.
Работает простое правило:
- Отбрасываете знак минуса
- Делите числа как обычно
- А далее, если первое число (делимое), было со знаком минус, к результату добавляете знак минус.
Пример №5
И пробуем теперь запустить программу на компьютере — один из описанных выше примеров: