Как проверить, есть ли остаток от деления чисел в С++?
С математической точки зрения, операция вычисления остатка в C/С++ для отрицательных чисел, например -11 % 8 == -3 , выдаёт не тот результат к которому мы привыкли со школьной скамьи. Конечно, это вопрос договорённости, но. Эта проблема иногда вызывает недоумение и горячие споры.
Если задача определить лишь отсутствие остатка, тогда достаточно % . Однако, есть частное решение когда делитель — это число степени 2. Этот же способ является наиболее простым для определения остатка от деления на числа больше 1 равные степени 2.
int a; int b; //2 в степени n if (a & (b - 1)) //остаток от деления присутствует. Например, -11 & (8 - 1) == 5 else //остаток равен нулю. Например, -8 & (8 - 1) == 0
Почему это важно? Рассмотрим последовательность mod(n, 4)
Для n&(4-1) последовательность периодическая
n -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 n&3 3 * * * * 2 * * * * 1 * * * * 0 * * * * *
Для n%4 последовательность, вообще говоря, непериодическая
n -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 n%4 3 * * 2 * * 1 * * 0 * * * * * -1 * * -2 * * -3 * *
Работать с периодической последовательностью гораздо приятней там где требуется соблюдать равные интервалы между событиями. Можно соорудить конструкцию типа
switch (i & 3) < case 0: /*событие 1*/; break; case 1: /*событие 2*/; break; case 2: /*событие 3*/; break; case 3: /*событие 4*/; break; >
и быть уверенным, что каждое событие будет возникать с завидной регулярностью независимо от знака i и дополнительных case не потребуется.
Арифметические действия в языке Си
Программы работают с данными. Зачастую данные представляют собой числа. В этом уроке, как вы наверное догадались, мы будем заниматься изучением того, как и что в языке Си можно делать с числами. Начнём с арифметики.
Компилятор языка Си понимает все основные арифметические операции, которые вам известны со школы. Плюс есть несколько дополнительных.
Основные арифметические операторы языка Си.
+ оператор сложения
— оператор вычитания
* оператор умножения
% оператор взятия остатка от деления
/ оператор деления
Следующая программа иллюстрирует использование первых четырёх из них. Кстати, обратите внимание на то, как с помощью функции printf вывести на экран символ % .
#include int main(void)
Результат работы этой программы представлен на следующем рисунке.
Рис.5 Использование арифметических действий в Си.
Всё чётко и понятно. Никаких неожиданностей. А теперь попробуем получить частное двух чисел. Т.к. результат должен получиться 3.5, то res объявим как float .
#include int main(void)< int a=7, b=2; float res; res = a/b; printf("%d / %d = %f\n",a,b,res); return 0; >
Как видите, результат получился не тот, что мы ожидали. Это одна из особенностей оператора деления в языке Си.
При делении значение целого типа на значение целого типа результат тоже получается целого типа.
Так уж устроен язык Си. Поэкспериментируйте, попробуйте любые другие целые числа.
Вычислить результат целочисленного деления легко. Поделите числа и отбросьте всё, что получилось в дробной части.
Пример: Как получить результат целочисленного деления
7/2 = 3.5 → 3
11/3 = 3.66 → 3
2/5 = 0.4 → 0
Для того чтобы получить тот результат, который мы в данном случае ожидаем, одно из значений нужно сделать вещественным. Сделать это проще простого. Для этого необходимо рядом с ним в скобках записать float .
Посмотрим на нашем примере:
#include int main(void)< int a=7, b=2; float res; res = (float)a/b; printf("%d / %d = %f\n",a,b,res); return 0; >
Теперь результат будет тот, что мы ожидали. Проделанный нами трюк называется явным преобразованием типа .
Явное преобразование (приведение) типа.
Если какое-то значение нужно привести к другому типу, нужно перед этим значением в скобках написать название требуемого типа.
Листинг 4. Примеры явного преобразования типа
int a=7, b; float g= 9.81,v; b = (int) g; //приводим значение 9.81 к типу int, получим 9 v= (float)a; // приводим значение 7 к типу float, получим 7.0
Важный момент: преобразуется не тип исходной переменной, а только лишь значение, которое используется в выражении. В следующем видео-фрагменте об этом говорится подробнее.
Обратите внимание, что, когда мы преобразовываем целое значение в вещественное, ничего особенного не происходит, т.к. вещественные числа включают в себя целые.
Совсем иная ситуация, когда мы от вещественного переходим к целому. При этом переходе у нас теряется вся дробная часть. Не забывайте об этом.
Картинка, показывающая различия между операциями взятие остатка, целочисленного деления и обычного деления.

Рис.2 Деление, целочисленное деление и остаток от деления.
Сохрани в закладки или поддержи проект.
Практика
Решите предложенные задачи:

Для удобства работы сразу переходите в полноэкранный режим
Исследовательские задачи для хакеров
- Подумайте и приведите примеры, когда обычное деление не имеет смысла. Например, деление трёх лицензионных ключей от программы между двумя людьми. Зачем кому-то нужна половина лицензионного ключа? (если, конечно, он не занимается reverse engineering).
- Что происходит при делении на ноль в вашей системе?
Дополнительные материалы
- Дополнительные задачи с автоматической проверкой решения из курса » Введение в программирование (C++) » от компании Яндекс. не беспокойтесь, что курс по С++. Удаляйте заготовку из поля для решения и спокойно вставляйте код на Си. Проверяющая система его будет нормально воспринимать.
Как найти остаток от деления в си
Форумчанин
Регистрация: 16.02.2009
Сообщений: 555
Получить остаток от деления
Як проверить есть ли у числа остаток от деления?!
#include "iostream" #include using namespace std; int main() < float l, b; cout>b; l=sqrt(b); cout system("pause"); >
Регистрация: 19.12.2008
Сообщений: 5,788
| проверить есть ли у числа остаток от деления?! |
Оператор «%«:
a = b % c; // в a остаток от деления b на c
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.
___________________________________ ___________________________________ _______
[=Правила форума=] _____ [Поиск] _____ [Литература по С++] ____ [Литература. Паскаль]
Пользователь
Регистрация: 27.07.2008
Сообщений: 30
if(a[i] % t)
где t это число остаток от деления на кот ты хочешь посмотреть.
Последний раз редактировалось KVF; 25.02.2009 в 21:49 .
Форумчанин
Регистрация: 16.02.2009
Сообщений: 555
Не получаетса как зделать есле число имеет остачу ввыводим ДА!
Регистрация: 19.12.2008
Сообщений: 5,788
#include #include using namespace std; int main()< int N,k; cin>>N>>k; if(N%k) cout
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.
___________________________________ ___________________________________ _______
[=Правила форума=] _____ [Поиск] _____ [Литература по С++] ____ [Литература. Паскаль]
Форумчанин
Регистрация: 16.02.2009
Сообщений: 555
using namespace std; int main() < float l, b; cout>b; l=sqrt(b); cout > system("pause"); > ERROR!
5.3 – Остаток от деления и возведение в степень
Оператор остатка от деления – это оператор, который возвращает остаток после целочисленного деления. Например, 7/4 = 1 и остаток 3 . Следовательно, 7 % 4 = 3 . В качестве другого примера, 25/7 = 3 и остаток 4, таким образом, 25 % 7 = 4 . Оператор остатка от деления работает только с целочисленными операндами.
Этот оператор наиболее полезен для проверки того, делится ли одно число без остатка на другое число: если x % y принимает значение 0, то мы знаем, что x без остатка делится на y .
#include int main() < std::cout ; std::cin >> x; std::cout ; std::cin >> y; std::cout
Вот результаты нескольких запусков этой программы:
Enter an integer: 6 Enter another integer: 3 The remainder is: 0 6 is evenly divisible by 3
Enter an integer: 6 Enter another integer: 4 The remainder is: 2 6 is not evenly divisible by 4
Теперь давайте рассмотрим пример, в котором второе число больше первого:
Enter an integer: 2 Enter another integer: 4 The remainder is: 2 2 is not evenly divisible by 4
Поначалу остаток от 2 может быть немного неочевидным, но это просто: 2/4 равно 0 (с использованием целочисленного деления), остаток 2. Когда второе число больше первого, второе число разделит первое число на 0 раз, поэтому первое число будет остатком.
Остаток от деления с отрицательными числами
Оператор остатка от деления также может работать с отрицательными операндами. x % y всегда возвращает результаты со знаком x .
Запускаем приведенную выше программу:
Enter an integer: -6 Enter another integer: 4 The remainder is: -2 -6 is not evenly divisible by 4
Enter an integer: 6 Enter another integer: -4 The remainder is: 2 6 is not evenly divisible by -4
В обоих случаях вы можете видеть, что остаток принимает знак первого операнда.
Предупреждение
До C++11 оператор остатка от деления с отрицательным операндом мог давать как положительный, так и отрицательный результат. В C++11 это стало предсказуемым.
Где оператор возведения в степень?
Вы заметите, что оператор ^ (обычно используемый для обозначения возведения в степень в математике) – в C++ это побитовая операция XOR (исключающее ИЛИ) (описанная в уроке «O.3 – Битовые манипуляции с побитовыми операторами и битовыми масками»). В C++ нет оператора возведения в степень.
Чтобы выполнить возведение в степень в C++, включите с помощью #include заголовочный файл и используйте функцию pow() :
#include double x< std::pow(3.0, 4.0) >; // 3 в 4-й степени
Обратите внимание, что параметры (и возвращаемое значение) функции pow() имеют тип double . Из-за ошибок округления в числах с плавающей запятой результаты pow() могут быть неточными (даже если вы передадите ей целочисленные значения или целые числа).
Если вы хотите выполнить целочисленное возведение в степень, лучше всего использовать для этого свою собственную функцию. Следующая функция реализует целочисленное возведение в степень (с использованием для повышения эффективности неинтуитивного алгоритма «возведения в возведения в квадрат»):
#include // for std::int_fast64_t // примечание: exp должно быть неотрицательным std::int_fast64_t pow(int base, int exp) < std::int_fast64_t result< 1 >; while (exp) < if (exp & 1) result *= base; exp >>= 1; base *= base; > return result; >
Не волнуйтесь, если вы не понимаете, как работает эта функция – чтобы вызывать ее, вам не нужно понимать ее внутреннюю работу.
#include #include // для std::int_fast64_t // примечание: exp должно быть неотрицательным std::int_fast64_t powint(int base, int exp) < std::int_fast64_t result< 1 >; while (exp) < if (exp & 1) result *= base; exp >>= 1; base *= base; > return result; > int main() < std::cout
Данная программа выводит следующее:
13841287201
Предупреждение
В подавляющем большинстве случаев целочисленное возведение в степень приведет к переполнению целочисленного типа. Вероятно, именно поэтому такая функция не была включена в стандартную библиотеку.
Небольшой тест
Вопрос 1
Что будет результатом вычисления следующего выражения? 6 + 5 * 4 % 3
Поскольку * и % имеют более высокий приоритет, чем + , + будет вычисляться последним. Мы можем переписать наше выражение как 6 + (5 * 4 % 3) . Операторы * и % имеют одинаковый приоритет, поэтому мы должны учитывать ассоциативность для их вычисления. Ассоциативность для операторов * и % – слева направо, поэтому сначала мы вычисляем левый оператор. Мы можем переписать наше выражение так: 6 + ((5 * 4) % 3) .
6 + ((5 * 4) % 3) = 6 + (20 % 3) = 6 + 2 = 8
Вопрос 2
Напишите программу, которая просит пользователя ввести целое число и сообщает пользователю, четное это число или нечетное. Напишите функцию с именем isEven() , которая возвращает true (истину), если переданное ей целое число четное, и false (ложь) в противном случае. Чтобы проверить, является ли целочисленный параметр четным, используйте оператор остатка от деления.
Подсказка: в этой программе вам нужно будет использовать операторы if и оператор сравнения ( == ). Если вам нужно напомнить, как это сделать, смотрите урок «4.9 – Логические (булевы) значения».
Ваша программа должна давать следующий вывод:
Enter an integer: 5 5 is odd
#include bool isEven(int x) < // если x % 2 == 0, наше число делится на 2 без остатка, // что означает, что число должно быть четным return (x % 2) == 0; >int main() < std::cout ; std::cin >> x; if (isEven(x)) std::cout
Примечание: у вас может возникнуть соблазн написать функцию isEven() следующим образом:
bool isEven(int x)
Хотя это работает, но это сложнее, чем должно быть. Давайте посмотрим, как это можно упростить. Во-первых, давайте вытащим условное выражение if и присвоим его отдельному логическому значению:
bool isEven(int x) < bool isEvenNumber = (x % 2) == 0; if (isEvenNumber) // isEvenNumber равно true return true; else // isEvenNumber равно false return false; >
Теперь обратите внимание, что оператор if выше, по сути, говорит: «Если isEvenNumber равно true , вернуть true , в противном случае, если isEvenNumber равно false , вернуть false ». Если это так, мы можем просто вернуть isEvenNumber :
bool isEven(int x)
И в этом случае, поскольку мы используем переменную isEvenNumber только один раз, мы могли бы также исключить и ее:
bool isEven(int x)