5.3 – Остаток от деления и возведение в степень

Добавлено 3 мая 2021 в 16:11

Оператор остатка от деления

Оператор остатка от деления – это оператор, который возвращает остаток после целочисленного деления. Например, 7/4 = 1 и остаток 3. Следовательно, 7 % 4 = 3. В качестве другого примера, 25/7 = 3 и остаток 4, таким образом, 25 % 7 = 4. Оператор остатка от деления работает только с целочисленными операндами.

Этот оператор наиболее полезен для проверки того, делится ли одно число без остатка на другое число: если x % y принимает значение 0, то мы знаем, что x без остатка делится на y.

#include <iostream>
 
int main()
{
	std::cout << "Enter an integer: ";
	int x{};
	std::cin >> x;
 
	std::cout << "Enter another integer: ";
	int y{};
	std::cin >> y;
 
	std::cout << "The remainder is: " << x % y << '\n';
 
	if ((x % y) == 0)
		std::cout << x << " is evenly divisible by " << y << '\n';
	else
		std::cout << x << " is not evenly divisible by " << y << '\n';
 
	return 0;
}

Вот результаты нескольких запусков этой программы:

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 заголовочный файл <cmath> и используйте функцию pow():

#include <cmath>
 
double x{ std::pow(3.0, 4.0) }; // 3 в 4-й степени

Обратите внимание, что параметры (и возвращаемое значение) функции pow() имеют тип double. Из-за ошибок округления в числах с плавающей запятой результаты pow() могут быть неточными (даже если вы передадите ей целочисленные значения или целые числа).

Если вы хотите выполнить целочисленное возведение в степень, лучше всего использовать для этого свою собственную функцию. Следующая функция реализует целочисленное возведение в степень (с использованием для повышения эффективности неинтуитивного алгоритма «возведения в возведения в квадрат»):

#include <cstdint> // 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 <iostream>
#include <cstdint> // для 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 << powint(7, 12); // 7 в 12-ой степени
 
	return 0;
}

Данная программа выводит следующее:

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 <iostream>
 
bool isEven(int x)
{
    // если x % 2 == 0, наше число делится на 2 без остатка,
    // что означает, что число должно быть четным
    return (x % 2) == 0;
}
 
int main()
{
    std::cout << "Enter an integer: ";
    int x{};
    std::cin >> x;
 
    if (isEven(x))
        std::cout << x << " is even\n"; // число четное
    else
        std::cout << x << " is odd\n"; // число нечетное
 
    return 0;
}

Примечание: у вас может возникнуть соблазн написать функцию isEven() следующим образом:

bool isEven(int x)
{
    if ((x % 2) == 0)
        return true;
    else
        return false;
}

Хотя это работает, но это сложнее, чем должно быть. Давайте посмотрим, как это можно упростить. Во-первых, давайте вытащим условное выражение 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)
{
    bool isEvenNumber = (x % 2) == 0;
    return isEvenNumber;
}

И в этом случае, поскольку мы используем переменную isEvenNumber только один раз, мы могли бы также исключить и ее:

bool isEven(int x)
{
    return (x % 2) == 0;
}

Теги

C++ / CppДля начинающихОбучениеОператор (программирование)Программирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.