From fee3a74e35b19be0bd24b584cff7e56a790fb1cf Mon Sep 17 00:00:00 2001 From: Shri Prakash Bajpai <68155959+Shri2206@users.noreply.github.com> Date: Fri, 30 Oct 2020 01:52:32 +0530 Subject: [PATCH] feat: Add modular_exponentiation.cpp (#1276) * Add modular_exponentiation * Delete modular_exponentiation * Add modular_exponentiation * Update and rename modular_exponentiation to modular_exponentiation.cpp * Update modular_exponentiation.cpp * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * updating DIRECTORY.md * clang-format and clang-tidy fixes for 4b93d5a5 * Update modular_exponentiation.cpp * Update modular_exponentiation.cpp * Update modular_exponentiation.cpp * Update modular_exponentiation.cpp * Update modular_exponentiation.cpp * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * clang-format and clang-tidy fixes for 053aea0b * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update modular_exponentiation.cpp Co-authored-by: David Leal Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + math/modular_exponentiation.cpp | 89 +++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 math/modular_exponentiation.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index be27c717f..d2aa95ba9 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -146,6 +146,7 @@ * [Least Common Multiple](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/least_common_multiple.cpp) * [Magic Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/magic_number.cpp) * [Miller Rabin](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/miller_rabin.cpp) + * [Modular Exponentiation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_exponentiation.cpp) * [Modular Inverse Fermat Little Theorem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_inverse_fermat_little_theorem.cpp) * [Number Of Positive Divisors](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/number_of_positive_divisors.cpp) * [Power For Huge Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/power_for_huge_numbers.cpp) diff --git a/math/modular_exponentiation.cpp b/math/modular_exponentiation.cpp new file mode 100644 index 000000000..01410860f --- /dev/null +++ b/math/modular_exponentiation.cpp @@ -0,0 +1,89 @@ +/** + * @file + * @brief C++ Program for Modular Exponentiation Iteratively. + * @details The task is to calculate the value of an integer a raised to an + * integer exponent b under modulo c. + * @note The time complexity of this approach is O(log b). + * + * Example: + * (4^3) % 5 (where ^ stands for exponentiation and % for modulo) + * (4*4*4) % 5 + * (4 % 5) * ( (4*4) % 5 ) + * 4 * (16 % 5) + * 4 * 1 + * 4 + * We can also verify the result as 4^3 is 64 and 64 modulo 5 is 4 + * + * @author [Shri2206](https://github.com/Shri2206) + */ +#include /// for assert +#include /// for io operations + +/** + * @namespace math + * @brief Mathematical algorithms + */ +namespace math { +/** + * @brief This function calculates a raised to exponent b under modulo c using + * modular exponentiation. + * @param a integer base + * @param b unsigned integer exponent + * @param c integer modulo + * @return a raised to power b modulo c + */ +uint64_t power(uint64_t a, uint64_t b, uint64_t c) { + uint64_t ans = 1; /// Initialize the answer to be returned + a = a % c; /// Update a if it is more than or equal to c + if (a == 0) { + return 0; /// In case a is divisible by c; + } + while (b > 0) { + /// If b is odd, multiply a with answer + if (b & 1) { + ans = ((ans % c) * (a % c)) % c; + } + /// b must be even now + b = b >> 1; /// b = b/2 + a = ((a % c) * (a % c)) % c; + } + return ans; +} + +} // namespace math + +/** + * Function for testing power function. + * test cases and assert statement. + * @returns `void` + */ +static void test() { + uint32_t test_case_1 = math::power(2, 5, 13); + assert(test_case_1 == 6); + std::cout << "Test 1 Passed!" << std::endl; + + uint32_t test_case_2 = math::power(14, 7, 15); + assert(test_case_2 == 14); + std::cout << "Test 2 Passed!" << std::endl; + + uint64_t test_case_3 = math::power(8, 15, 41); + assert(test_case_3 == 32); + std::cout << "Test 3 Passed!" << std::endl; + + uint64_t test_case_4 = math::power(27, 2, 5); + assert(test_case_4 == 4); + std::cout << "Test 4 Passed!" << std::endl; + + uint16_t test_case_5 = math::power(7, 3, 6); + assert(test_case_5 == 1); + std::cout << "Test 5 Passed!" << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // execute the tests + return 0; +}