Целочисленное деление несколько отличается от обычного. Целочисленное деление — это то же caмoe деление, которое вы изучали, когда ходили в первый класс. При делении числа 21 на число 4 (21/4) в случае целочисленного деления в ответе получается 5 и остаток 1.

Чтобы получить остаток, нужно число 21 разделить по модулю 4 (21 % 4), в результате получим остаток 1.

Операция деления по модулю иногда оказывается весьма полезной, например, если вы захотите вывести из ряда чисел каждое десятое значение. Любое число, результат деления которого по модулю 10 равен нулю, является кратным десяти, т.е. делится на 10 без остатка. Так, результат выражения 1 % 10 равен 1; 2 % 10 равен 2 и т.д.; а 10 % 10 равен 0. Результат от деления 11 % 10 снова равен 1; 12 % 10 снова равен 2; и так можно продолжать до следующего числа, кратного 10, которым окажется 20. Мы воспользуемся этим методом при рассмотрении циклов на занятии 7.

Вопросы и ответы

При делении 5 на 3 я получаю в ответе 1. В чем моя ошибка?

При делении одного целого числа на другое в качестве результата вы также получите целое число. Следовательно, 5/3 равно 1.

Для получения дробного результата нужно использовать вещественные числа. Выражение 5,0 / 3,0 даст дробный ответ: 1,66667.

Если ваш метод принимает в качестве параметров целочисленные значения, нужно привести их к типу float.

Вопросы и ответы: Выполняя операцию приведения типа переменной, вы заставляете компилятор изменить ее тип. Приэтом вы как будто говорите своемукомпилятору:"Я знаю, что делаю". Было бы неплохо, если бы это оказалось правдой, поскольку компилятор как бы отвечает вам: "Как скажете, босс: вся ответственность ложится на вас". В данном случае мы хотим сказать компилятору: "Я понимаю, что ты считаешь это значение целым, но я знаю, что делаю: это действительно вещественное значение". Для приведения типа существует два способа. Можно использовать приведение типа в старом стиле С или новый улучшенный оператор ANSIstatic_cast. Оба варианта демонстрируются в листинге 4.3.

Листинг 4.3. Приведение переменной к типу float

3: void intDiv(int x, int y)

6: cout (y); // современный стиль

13: float c = a / b;

Совместное использование математических операторов с операторами присваивания

Нет ничего необычного в том, чтобы к переменной прибавить некоторое значение, а затем присвоить результат той же переменной. Если у вас есть переменная myAge и вы хотите увеличить ее значение на два, можно записать следующее:

temp = myAge + 2; // складываем 5 + 2 и результат помещаем в

temp myAge = temp; // значение возраста снова помещаем в myAge

Однако этот метод грешит излишествами. В языке C++ можно поместить одну и ту же переменную по обе стороны оператора присваивания, и тогда предыдущий блок сведется лишь к одному выражению:

myAge = myAge + 2;

В алгебре это выражение рассматривалось бы как бессмысленное, но в языке C++ оно читается следующим образом: добавить два к значению переменной myAge и присвоить результат переменной myAge.

Существует еще более простой вариант предыдущей записи, хотя его труднее читать:

Этот оператор присваивания с суммой (+=) добавляет r-значение к l-значению, а затем снова записывает результат в l-значение. Если бы до начала выполнения выражения переменная myAge имела значение 4, то после ее выполнения значение переменной myAge стало бы равным 6.

Помимо оператора присваивания с суммой существуют также оператор присваивания с вычитанием (-=), делением (/=), умножением (*=) и делением по модулю (%=).

Инкремент декремент

Очень часто в программах к переменным добавляется (или вычитается) единица. В языке C++ увеличение значения на 1 называется инкрементом, а уменьшение на 1 — декрементом. Для этих действий предусмотрены специальные операторы.

Оператор инкремента (++) увеличивает значение переменной на 1, а оператор декремента (—) уменьшает его на 1. Так, если у вас есть переменная С и вы хотите прирастить ее на единицу, используйте следующее выражение:

C++; // Увеличение значения С на единицу

Это же выражение можно было бы записать следующим образом:

что, в свою очередь, равносильно выражению.

Префикс и постфикс

Как оператор инкремента, так и оператор декремента работает в двух вариантах: префиксном и постфиксном. Префиксный вариант записывается перед именем переменной (++myAge), а постфиксный — после него (myAge++).

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

Семантика префиксного оператора следующая: инкрементируем значение, а затем считываем его. Семантика постфиксного оператора иная: считываем значение, а затем декрементируем оригинал.

На первый взгляд это может выглядеть несколько запутанным, но примеры легко проясняют механизм действия этих операторов. Если x — целочисленная переменная, значение которой равно 5, и, зная это, вы записали

то тем самым велели компилятору инкрементировать переменную x (сделав ее равной 6), а затем присвоить это значение переменной а. Следовательно, значение переменной а теперь равно 6 и значение переменной x тоже равно 6. Если же, после этого вы записали

то тем самым велели компилятору присвоить переменной b текущее значение переменной x (6), а затем вернуться назад к переменной x и инкрементировать ее. В этом случае значение переменной b равно 6, но значение переменной x уже равно 7. В листинге 4.4 продемонстрировано использование обоих типов операторов инкремента и декремента.

Листинг 4.4. Примеры использования префиксных и постфиксных операторов

1: // Листинг 4.4. Демонстрирует использование

2: // префиксных и постфиксных операторов

3: // инкремента и декремента

7: int myAge = 39; // инициализируем две целочисленные переменные

8: int yourAge = 39;

9: cout yourAge; // значение переменной myAge больше значения переменной yourAge? также возвратит 0 (или false).

Предупреждение: Многие начинающие программировать на языке C++ путают оператор присваивания (=) с оператором равенства (==). Случайное использование не того оператора может привести к такой ошибке, которую трудно обнаружить.

Всего в языке C++ используется шесть операторов отношений: равно (==), меньше ( ), меньше или равно ( =) и не равно (!=). В табл. 4.1 не только перечислены все операторы отношений, но и приведены примеры их использования.

Рекомендуется:Помните, что операторы отношений true или false.

He рекомендуется: Не путайте оператор присваивания (=) с оператором равенства (==). Это одна из самых распространенных ошибок программирования на языке C++ — будьте начеку!

Ошибка! Недопустимый объект гиперссылки.

Оператор if

Обычно программа выполняется по порядку, строка за строкой. Оператор if позволяет проверить условие (например, равны ли две переменные) и изменить ход выполнения программы, направив ее в другое русло, которое будет зависеть от результата сравнения. Простейшая форма оператора if имеет следующий вид:

Условие в круглых скобках может быть любым выражением, но обычно оно содержит операторы отношений. Если это выражение возвращает false, то последующий оператор пропускается. Если же оно возвращает значение true, то оператор выполняется. Рассмотрим следующий пример:

Здесь сравниваются значения переменных bigNumber и smallNumber. Если значение переменной bigNumber больше, то во второй строке этого программного фрагмента ее значение устанавливается равным значению переменной smallNumber.

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

Вот простой пример применения блока выражений:

  • написана командой Vertex Academy. Надеемся, что она Вам будет полезна. Приятного прочтения!
  • это одна из статей из нашего "Самоучителя по Java"

Ещё со школы мы знакомы с таким понятием как обычное деление:

С этим все понятно. А что же это за «зверь» такой, деление по модулю ? И звучит то так угрожающе. А на самом деле всё очень и очень просто. Давайте разбираться.
Что Вам нужно понимать:

  1. Деление по модулю – это оператор

Как работает оператор сложения, вычитания и т.д. наверняка Вы уже знаете. А вот за что отвечает деление по модулю поймёте буквально через пару минут. Немного терпения.

  1. Деление по модулю обозначается вот таким знаком: %
  2. Деление по модулю иногда называют mod. То есть если увидите название mod, знайте, речь идет об операторе деление по модулю.
  3. В чём суть оператора? Деление по модулю даёт остаток от деления.

Давайте посмотрим на примерах как это работает.

Пример №1

Необходимо разделить 9 на 4, используя:

  • обычное деление, как нас учили в школе
  • деление по модулю

Логику работы оператора деления по модулю Вы уже поняли. Самое время попробовать запустить пример на своём компьютере:

Если Вы запустите этот код на своём компьютере, то в консоль будет выведено такое число:

Пример №2

Необходимо разделить 17 на 5, используя:

  • обычное деление, как нас учили в школе
  • деление по модулю

И пробуем теперь запустить программу на компьютере:

Если Вы запустите этот код на своём компьютере, то в консоль будет выведено такое число:

Пример №3

Необходимо разделить 21 на 7, используя:

  • обычное деление, как нас учили в школе
  • деление по модулю

И пробуем теперь запустить программу на компьютере:

Если Вы запустите этот код на своём компьютере, то в консоль будет выведено такое число:

Пример №4

Необходимо разделить 7.6 на 2.9, используя:

  • обычное деление, как нас учили в школе
  • деление по модулю

И пробуем теперь запустить программу на компьютере:

Если Вы запустите этот код на своём компьютере, то в консоль будет выведено число, близкое к 1.8. Например, Вы можете увидеть какое-то такое число: 1.7999999999999998. Из-за определённых особенностей Java, которые мы будем с Вами рассматривать позже в других статьях, на разных компьютерах число будет немного отличаться. Но оно будет близкое по значению к 1.8

Итак, как Вы уже поняли, оператор деления по модулю вычисляет остаток от деления.

  1. Применяется к таким типам переменных:
  • Byte, short, Int, long – целочисленный тип переменных
  • Float, Double – числа с плавающей точкой
  • Отрицательные и положительные числа

Есть небольшой нюанс при использовании оператора деления по модулю с отрицательными и положительными числами.

Работает простое правило:

  1. Отбрасываете знак минуса
  2. Делите числа как обычно
  3. А далее, если первое число (делимое), было со знаком минус, к результату добавляете знак минус.

Пример №5

И пробуем теперь запустить программу на компьютере — один из описанных выше примеров:

Приготовьтесь, вас ждёт крайне педантичная статья, которая вполне может спасти вас на собеседовании или сэкономить несколько часов при вылавливании бага в продакшне!

Я сейчас активно работаю над вторым сезоном «Руководства для самозванца» и пишу о шифре RSA для SSH, который, очевидно, является самым загружаемым фрагментом кода в истории IT.

Хочется полностью разобраться в этой истории. Кто придумал этот шифр, как он работает, почему работает и будет ли работать в будущем. Сейчас я раскопал одну чертовски интересную историю. Я не криптоманьяк и вижу, как других буквально засасывает в эту область. Но мне это тоже интересно, потому что повсюду есть маленькие норки, а меня как сороку привлекают блестящие штучки в глубоких норках. Я также очень хорош в метафорах.

В любом случае: на прошлой неделе я узнал что-то странное и хочу поделиться: оказывается, mod и остаток от деления — не одно и то же. Действительно забавно то, что некоторые читатели при этих словах выпрыгивают со своих кресел и орут: «А ведь именно это я всегда пытался сказать вам и всем остальным!»

Позовите ребят из секты «mod не остаток»! Это для вас.

Я должен был изучить это, как и в прошлый раз, когда всплыла такая тема. Это одна из тех вещей, которые ты знаешь, но не запоминаешь. Когда вы применяете mod, то делите одно число на другое и берёте остаток. Итак: 5 mod 2 будет 1, потому что 5/2=2 с остатком 1.

Термин mod означает операцию modulo, с модулем 2 в данном случае. Большинство языков программирования используют % для обозначения такой операции: 5 % 2 = 1 .

Вот где мы попадаем в странную серую область.

Помню, как учил это в школе, а потом забыл. Существует тип математики, называемый «модульной арифметикой», которая имеет дело с циклическими структурами. Самый простой способ представить это — циферблат с циклом 12. Для математика циферблат — это mod 12 . Если хотите понять, можно ли равномерно разделить 253 часа на дни, то можете применить операцию 253 mod 24 , результатом будет 13, поэтому ответ «нет»! Мы можем ответить «да» только если результат 0.

Другой вопрос, который вы можете задать: «Если я выеду в 6 вечера, сколько времени будет по приезду через 16 часов?». Это будет 6 + 16 mod 12 , то есть 10.

Криптографы любят mod , потому что при использовании с действительно большими числами можно создать нечто, известное как «односторонние функции». Это специальные функции, которые позволяют легко вычислить что-то в одном направлении, но не в обратном.

Если я скажу вам, что 9 является результатом возведения в квадрат, вы можете легко определить, что на входе было 3. Перед вами весь процесс от начала до конца. Если я скажу, что 9 является результатом mod 29 , то будет сложнее понять, что на входе.

Криптографам нравится эта идея, потому что они могут использовать деление с остатком с гигантскими простыми числами для генерации криптографических ключей. Это совсем другая история: если хотите прочитать об этом, то можете купить книгу или, ещё лучше, поддержать мои усилия написать её.

Впрочем, не будем отклоняться от темы.

Теперь переходим к сути: modulo и простой остаток одинаковы, когда числа положительны, но отличаются в случае отрицательных чисел.

Рассмотрим такую задачу:

Каково значение x ? Делим числа и получаем 7 как остаток от 12. Это верный ответ. Как насчет такого:

Используя обычную математику, мы можем умножить -12 на -1, что даёт 12, и у нас по-прежнему остаётся 7, поэтому наш ответ снова 7.

JavaScript с этим согласен:

C# тоже согласен:

Google согласен с первым утверждением, но не согласен со вторым:

Ruby согласен с Google:

Во имя Дейкстры, что здесь происходит?

Чтобы ответить на вопрос, следует понять разницу между остатком и modulo. Программисты объединяют эти операции, но не должны этого делать, потому что они дают одинаковый результат только в случае, если делитель (в нашем случае 12) положителен. Вы можете легко отправить баги в продакшн, если делитель отрицательный.

Но почему существует разница? Рассмотрим положительный делитель 19 mod 12 на часах:

Конечный результат 7. Мы это знаем и мы можем доказать математически. Но что насчёт 19 mod -12 ? Здесь нужно использовать другие часы:

Модуль равен -12, и мы не можем игнорировать или изменить его, умножив на -1, поскольку модульная арифметика так не работает. Единственный способ правильно рассчитать результат — переставить метки на часах так, чтобы мы двигались от -12 или вращали часы против часовой стрелки, что даёт тот же результат.

Почему не начать метки с -1, двигаясь к -2, и т.д.? Потому что в таком случае мы будем двигаться назад и постоянно уменьшать результат, пока не достигнем -12, и в этот момент сделаем прыжок +12, а modulo так не работает.

Прежде чем назвать меня сумасшедшим и начать гуглить тему: это известный факт. На самом деле MDN (Mozilla Developer Network) даже дошла до того, чтобы назвать % операцией «остатка» (remainder), а не modulo:

Оператор remainder возвращает остаток от деления одного операнда на другой. Он всегда принимает знак делимого.

Вот что Эрик Липперт, один из богов C#, говорит о modulo в C#:

Однако это совсем не то, что оператор % реально делает в C#. Оператор % не является каноническим оператором modulus, это оператор остатка.

А как на вашем языке?

Могу понять, если вы дочитали досюда, а теперь чешете голову и задаётесь вопросом, стоит ли беспокоиться. Думаю, что стоит по двум причинам:

  1. Я представляю, как этот вопрос займёт меня врасплох на собеседовании.
  2. Я представляю, как этот попадёт в продакшн, а разработчики будут несколько часов выяснять, почему математика не работает.

Это также забавный факт на случай, если рядом появится ваш педантичный друг-программист.