Search

5.3 — Modulus and Exponentiation

The modulus operator

The modulus operator (also informally known as the remainder operator) is an operator that returns the remainder after doing an integer division. For example, 7 / 4 = 1 remainder 3. Therefore, 7 % 4 = 3. As another example, 25 / 7 = 3 remainder 4, thus 25 % 7 = 4. Modulus only works with integer operands.

Modulus is most useful for testing whether a number is evenly divisible by another number: if x % y evaluates to 0, then we know that x is evenly divisible by y.

Here are a couple runs of this program:

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

Modulus with negative numbers

The modulus operator can also work with negative operands. As of C++11, x % y always returns results with the sign of x.

Running the above program:

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

In both cases, you can see the remainder takes the sign of the first operand.

Warning

Prior to C++11, modulus with a negative operand could result in either a positive or negative result. This was made predictable in C++11.

Where’s the exponent operator?

You’ll note that the ^ operator (commonly used to denote exponentiation in mathematics) is a Bitwise XOR operation in C++ (covered in lesson O.3 -- Bit manipulation with bitwise operators and bit masks). C++ does not include an exponent operator.

To do exponents in C++, #include the <cmath> header, and use the pow() function:

Note that the parameters (and return value) of function pow() are of type double. Due to rounding errors in floating point numbers, the results of pow() may not be precise (even if you pass it integers or whole numbers).

If you want to do integer exponentiation, you’re best off using your own function to do so. The following function implements integer exponentiation (using the non-intuitive “exponentiation by squaring” algorithm for efficiency):

Don’t worry if you don’t understand how this function works -- you don’t need to understand it in order to call it.

Produces:

13841287201

Warning

In the vast majority of cases, integer exponentiation will overflow the integral type. This is likely why such a function wasn’t included in the standard library in the first place.

Quiz time

Question #1

What does the following expression evaluate to? 6 + 5 * 4 % 3

Show Solution

Question #2

Write a program that asks the user to input an integer, and tells the user whether the number is even or odd. Write a function called isEven() that returns true if an integer passed to it is even, and false otherwise. Use the modulus operator to test whether the integer parameter is even.

Hint: You’ll need to use if statements and the comparison operator (==) for this program. See lesson 4.9 -- Boolean values if you need a refresher on how to do this.

Your program should match the following output:

Enter an integer: 5
5 is odd

Show Solution


5.4 -- Increment/decrement operators, and side effects
Index
5.2 -- Arithmetic operators

50 comments to 5.3 — Modulus and Exponentiation

  • sami

    " the results of pow() may not be precise (even if you pass it integers or whole numbers)."

    Do you mean when exponent is a NEGATIVE integer, right? Because when both of them are positive integers (16 ^ 80), then I can't get how they could produce a floating point number with some fraction!

  • chikennoodles

    I tried this but it took a lot of steps when i use breakpoints to debug

  • Slyminc

    i've realize that in bool y argument in printAns() is actually returning true(1)/false(0) instead of returning the actual 'x' variable (which is just userInput() ). so in printAns(), i've also included the actual 'x' variable for if statements to execute the if/else comparison. in short, isEven(x) is not printing userInput() value, rather 1(true)/0(false) value.

    idk, maybe this comment will help someone out.

  • Alan Wynne

    What about this code for function isEven:

    return !(x % 2 ) ;

  • "To do exponents in C++, #include the <cmath> header, and use the pow() function:" pow() works fine with <iostream> alone. I'm guessing because it's included inside indirectly. Same for "#include <cstdint> // for std::int_fast64_t".

  • internet_laser

    Hi, I have a general question about writing functions in a program. In the example solution a lot of the work is handled within the main function. The way I approached this was to subdivide input, calculation & output into modular functions that the main program coordinates with calls & returns. Is there a more correct approach? Is it better to have a program that's more modular or simpler with less calls?

    • nascardriver

      Usually, the more functions you have, the better. Some of the examples here don't follow that, because the code is so simple. In practice, you should use many many functions, but not functions as simple as `isEven` (For the sake of this lesson, that's fine too).

      To your code, `result` is a `bool`. 1 is an integer. If you want to check if a `bool` is `true`, you don't need any comparisons.

  • Hishikesh Bania

    #include <cstdint> // for std::int_fast64_t

    // note: exp must be non-negative
    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;
    }

    if we put this in an another file and try to use then this code dont get compiled but if we try to use this in the single file where main function resides it gets compiled . why is it show ?

    ||=== Build: Debug in intergerexpofunc_for_future_use (compiler: GNU GCC Compiler) ===|
    C:\Program Files\CodeBlocks\MinGW\bin\..\lib\gcc\x86_64-w64-mingw32\8.1.0\..\..\..\..\x86_64-w64-mingw32\lib\..\lib\libmingw32.a(lib64_libmingw32_a-crt0_c.o):crt0_c.c:(.text.startup+0x2e)||undefined reference to `WinMain'|
    ||error: ld returned 1 exit status|
    ||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

    this type of error i get

  • Raffaello

    I did some testing, to try and figure out how std::pow works, and I ended up with this:

    (I compiled them individually, included the cmath header and did everything else right, I think) can you explain why that is? on the line that does not compile it throws the error: error: narrowing conversion of '2.56e+2' from '__gnu_cxx::__promote_2<int, int, double, double>::__type' {aka 'double'} to 'int' [-Wnarrowing]

    • nascardriver

      There is no `std::pow` for integers. No matter how you call `std::pow`, it returns a floating point type.
      List initialization {} doesn't allow narrowing conversions, ie. conversions that potentially cause loss of information. Because not all floating point numbers can be converted to an integer without loss of information, the initialization is illegal.
      We explain how to explicitly convert types later.

  • Gabe

    Question #2:

  • Kev

    This works on my compiler. Could I get some feedback? Thank you.

    • nascardriver

      `isEven` shouldn't do the printing, it should only return true/false depending on if the integer is even. Looks good otherwise.

  • Dudz

  • mmp52

    Is this function also suitable to general conventions:

    Where implicit conversion from integer to bool takes place

  • vova220v

  • Tom

    I'm very confused by what's happening here:

    We have an if statement that runs a function and gets back either a 1 or 0, but we don't ask the if statement to check if it's a 1 or 0, we just accept whatever we get and move on to the next line, and if we got something different than we do the else. Am I mistaken or are we just neglecting to check what the returned value is for the first if block and just finding out at runtime and assigning the correct cout sentence to it and calling it a day? Why not say "if (isEven(x) = 0)"? Is it because there can only be 2 possible responses and we just don't care about specifying? Very confused.

    • RJ

      The syntax of an if statement is, if (condition) statement;  the condition will always evaluate to a true or false value that's the purpose of and if statement. Your not ignoring the return value from isEven(x), basicly if "isEven(x)" returns 1 or any other number that's not zero (true) to the compiler it looks like this

      then the statement specified will execute, and if it returned 0 (false) it would look like this to the compiler

      .

  • Chris

    Ged,
    To avoid using std:: before cout and pow, try using:

  • Papi

    Hello.

    How bad is this code? Ignore the formatting pls

    • Raton

      Hi! I think it's recommended not to put zero at line 6 because the value of "integer" is immediately discarded (so the 0 doesn't really mean anything, just put: int integer{};). You can also add parenthesis at line 13: if ((number % 2) == 0), to make it easier to read. If you really want to follow best practices you could maybe also make isEven() return a Boolean value (the number's parity) and put the output part (with std::cout, etc.) in main(), or in another function (called in main()). You can also add a line feed (\n) at the end of the strings in line 14 and 16 to separate your output from the things printed by the compiler.

  • Tony98

    I'm always completing the exercises in different ways. Is it ok if I always create multiple simple functions to do all the jobs? Like this for this specific exercise:

    I find it much easier to create first all the simple functions and then call them on main, what do you think?
    Thanks again for the reply!

    • nascardriver

      Yes, it's better that way. Some of the examples are so short that the solution just crammed everything into 1 or 2 functions.
      Your call to `isEven` in line 29 doesn't do anything.

  • giang

    So can we use the pow() function for integers?? Because I try this function for integers and it worked

  • Kyle

    I did it different than you but ended up with the same results, is this fine? I am also a lot more comfortable with the way I did when compared to the way you did it, is that bad and should I try to change that mindset? I would also like to thank you for this book as I'm going to call it, it has been a God send.

    • Kyle

      I was examining question 2 again and I just realized you requested that we make a function that returns true or false, I missed that. Never mind my bit of code.

      • nascardriver

        Your code still shows that you understand the concepts asked for in this quiz. If your program prints anything, it's good to print a line feed (\n) at the end to prevent mixing output with other programs.

  • chai

    A little bit shorter but just as good?

    • nascardriver

      You're converting from int to bool. It does what it should, but can be harder to read than an explicit conversion via `==`.

      • koe

        I had the same idea.

        Would this code be slower than the quiz solution, or is it just a matter of clarity?

        • nascardriver

          It will probably produce exactly the same binary as the quiz. Your compiler is great at optimizing simple things. Do what you find easier to read, I prefer the comparison to 0.

  • Raul

    Thanks for the well-structured material!
    My approach:

    • nascardriver

      hi Raul!

      `isEven` isn't supposed to print anything, but return false/true depending on whether or not `x` is even. Try to implement it in a way that `main` does the printing.

      • Raul

        Thanks for the intervention, nascardriver.

  • Alex3>

    This is my way of solving this task:

    • nascardriver

      Hi!

      You're not using the return value of `isTrue`. Declare it `void`.
      `std::cin >> x` should be on its own line for better readability.
      If your program prints anything, the last thing it prints should be a line feed.
      "isTrue" is a poor name, it doesn't describe what the function does.

  • Knight

    How to fix this code? 0 appeared on the result.  Thanks.

  • Ged

    Why do we need to write std:: for pow? Cause it allows us to use it without std. Both codes work.

    • nascardriver

      declares its contents inside the `std` namespace. It also declares them outside for C compatibility, so you can use them without `std::`. To prevent name collisions and to make sure your code still works if the outside-declaration should ever be removed, I recommend using `std::pow`.

  • Hadal

    You forgot to include the word 'evenly' in the code output examples.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]