What Are the Remainder and Exponentiation Operations?

The remainder operator gives you what is left over after integer division, while exponentiation raises a number to a power. These operations are commonly needed in programming but work differently in C++ than you might expect from mathematics.

The remainder operator (operator%)

The remainder operator (sometimes called the modulo operator) returns what's left over after integer division. For instance, 13 / 3 = 4 with remainder 1, so 13 % 3 = 1. Similarly, 50 / 7 = 7 with remainder 1, so 50 % 7 = 1. This operator only works with integer types.

The remainder operator is particularly useful for checking if one number divides evenly into another. If a % b equals 0, then b divides evenly into a.

#include <iostream>

int main()
{
    std::cout << "Enter a number: ";
    int dividend{};
    std::cin >> dividend;

    std::cout << "Enter a divisor: ";
    int divisor{};
    std::cin >> divisor;

    std::cout << "Remainder: " << dividend % divisor << '\n';

    if ((dividend % divisor) == 0)
        std::cout << dividend << " is evenly divisible by " << divisor << '\n';
    else
        std::cout << dividend << " is not evenly divisible by " << divisor << '\n';

    return 0;
}

Sample runs:

Enter a number: 20
Enter a divisor: 5
Remainder: 0
20 is evenly divisible by 5
Enter a number: 20
Enter a divisor: 6
Remainder: 2
20 is not evenly divisible by 6

When the divisor is larger than the dividend, the result might seem unexpected at first:

Enter a number: 3
Enter a divisor: 10
Remainder: 3
3 is not evenly divisible by 10

This makes sense: 3 / 10 = 0 (integer division) with remainder 3. When the divisor exceeds the dividend, it "fits" zero times, leaving the entire dividend as the remainder.

Execution trace

Here's how 17 % 5 is calculated step-by-step:

Step Operation Result
1 Divide: 17 / 5 3 (integer division truncates)
2 Multiply: 3 * 5 15 (how much 5 "used up")
3 Subtract: 17 - 15 2 (what's left over)

So 17 % 5 = 2. The relationship is: dividend = (dividend / divisor) * divisor + (dividend % divisor).

Key Concept
The remainder operation answers: "If I have 17 items and pack them into groups of 5, how many items are left over?" This makes it perfect for tasks like determining if a number is even/odd, cycling through array indices, or formatting output every N items.

Remainder with negative numbers

The remainder operator handles negative operands. The sign of the result always matches the sign of the dividend (the left operand).

Enter a number: -20
Enter a divisor: 6
Remainder: -2
-20 is not evenly divisible by 6
Enter a number: 20
Enter a divisor: -6
Remainder: 2
20 is not evenly divisible by -6

Notice the remainder's sign matches the first operand in both cases.

Negative number edge cases

Expression Result Why
13 % 5 3 Both positive: 13 = 2*5 + 3
-13 % 5 -3 Negative dividend: sign matches -13
13 % -5 3 Negative divisor: sign matches 13
-13 % -5 -3 Negative dividend: sign matches -13
5 % 13 5 Divisor larger: nothing "fits"
-5 % 13 -5 Sign matches -5
Key Concept
The sign of the remainder ALWAYS matches the sign of the dividend (the first operand). The sign of the divisor never affects the result's sign.

Nomenclature note: The C++ standard refers to this as the "remainder" operator. While commonly called "modulo," that term can be confusing because mathematical modulo differs from C++'s operator% when negative numbers are involved.

For example, mathematically:

  • -17 modulo 5 = 3
  • -17 remainder 5 = -2

We prefer calling it the "remainder" operator for accuracy.

When the dividend might be negative, be careful with comparisons. You might write:

bool isOdd(int number)
{
    return (number % 2) == 1; // fails for negative odd numbers
}

This fails for negative odd numbers like -7, because -7 % 2 equals -1, not 1.

Instead, compare against 0, which works correctly regardless of sign:

bool isOdd(int number)
{
    return (number % 2) != 0; // works for positive and negative
}
Best Practice
When using the remainder operator, compare the result against `0` whenever possible to ensure correct behavior with negative numbers.

Where's the exponent operator?

You won't find an exponent operator in C++. The ^ symbol performs bitwise XOR, not exponentiation (covered in the Bit manipulation with bitwise operators and bit masks lesson).

For exponentiation, include the <cmath> header and use std::pow():

#include <cmath>

double result{std::pow(2.0, 8.0)}; // 2 to the 8th power = 256.0

Note that std::pow() uses double for parameters and return value. Floating-point calculations involve rounding errors, so results may not be perfectly precise even with whole numbers.

std::pow() is the whole story for floating-point work. Integers are where it gets awkward, and it is worth knowing why before you reach for a cast.

Because std::pow() computes in double, a result you expect to be exact can land a hair below the whole number. Truncating that with static_cast<int> then loses a whole unit:

#include <cmath>
#include <iostream>

int main()
{
    const double cubed{std::pow(5.0, 3.0)};

    std::cout << "as a double: " << cubed << '\n';
    std::cout << "truncated:   " << static_cast<int>(cubed) << '\n';
    std::cout << "rounded:     " << static_cast<int>(std::round(cubed)) << '\n';

    return 0;
}

This outputs:

as a double: 125
truncated:   125
rounded:     125

Here all three agree, and on most compilers small cases like this one will. The point is that nothing in the language promises they will. std::pow() is permitted to return 124.99999999999999 for an exponent large enough to strain a double, and truncation would turn that into 124. Rounding first costs nothing and removes the question.

Best Practice
When you need an integer power and std::pow() is the tool at hand, round before you cast: static_cast<int>(std::round(std::pow(base, exponent))). Truncating a floating-point result directly is how off-by-one bugs of exactly this shape get in.

The other limit is range, and it arrives faster than most people expect. A 32-bit int tops out just above two billion, so 2 to the 31st power already overflows it. Exponentiation grows fast enough that even modest inputs leave the type behind, which is a large part of why the standard library never shipped an integer version.

Writing your own integer power function is a reasonable exercise, and it needs a loop to multiply the base by itself the right number of times. Loops are the subject of a later chapter, so we will come back to it there rather than paste code you have not been taught to read yet.

Summary

  • Remainder operator (%): Returns what's left over after integer division (e.g., 13 % 3 = 1); also called modulo operator
  • Checking divisibility: If a % b == 0, then b divides evenly into a
  • Sign behavior: The remainder's sign always matches the sign of the dividend (left operand)
  • Terminology: C++ uses "remainder" (not "modulo") because mathematical modulo differs from operator% when negative numbers are involved
  • Comparing remainder results: Always compare against 0 when possible to ensure correct behavior with negative numbers (e.g., number % 2 != 0 instead of number % 2 == 1)
  • No exponent operator: C++ doesn't have an exponentiation operator; ^ performs bitwise XOR instead
  • std::pow(): Use std::pow() from <cmath> for floating-point exponentiation (e.g., std::pow(2.0, 8.0))
  • Integer results: Round before casting, static_cast<int>(std::round(std::pow(base, exponent))), because truncating a double that landed just short costs you a whole unit
  • Overflow risk: Powers outgrow int quickly (2 to the 31st already overflows a 32-bit int), which is why the standard library has no integer version

The remainder operator is essential for many common programming tasks like checking even/odd numbers or cycling through ranges. Understanding its sign behavior with negative numbers prevents subtle bugs. For exponentiation, std::pow() covers floating-point work; integers need a round-then-cast and an eye on how fast powers overflow.