Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ You can add new algorithms or data structures that are **not present in the repo
- Do not update [`README.md`](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/README.md) along with other changes. First, create an issue and then link to that issue in your pull request to suggest specific changes required to [`README.md`](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/README.md).
- The repository follows [Doxygen](https://www.doxygen.nl/manual/docblocks.html) standards and auto-generates the [repository website](https://thealgorithms.github.io/C-Plus-Plus). Please ensure the code is documented in this structure. A sample implementation is given below.

##### Example: Info and Caution Blocks

When writing contribution rules or documentation, you may use special markdown blocks to highlight important information.

**Info block example:**

> [!INFO]
> Use this block to provide helpful context or guidance for contributors.

**Caution block example:**

> [!CAUTION]
> Avoid adding new implementations that duplicate existing algorithms in the repository.

#### Test

- Make sure to add examples and test cases in your `main()` function.
Expand Down
123 changes: 83 additions & 40 deletions math/binary_exponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,110 @@
* Calculate \f$a^b\f$ in \f$O(\log(b))\f$ by converting \f$b\f$ to a
* binary number. Binary exponentiation is also known as exponentiation by
* squaring.
* @note This is a far better approach compared to naive method which
* provide \f$O(b)\f$ operations.
*
* @note This is a far better approach compared to the naive method which
* provides \f$O(b)\f$ operations.
*
* Example:
* </br>10 in base 2 is 1010.
*
* 10 in base 2 is 1010.
*
* \f{eqnarray*}{
* 2^{10_d} &=& 2^{1010_b} = 2^8 * 2^2\\
* 2^1 &=& 2\\
* 2^2 &=& (2^1)^2 = 2^2 = 4\\
* 2^4 &=& (2^2)^2 = 4^2 = 16\\
* 2^8 &=& (2^4)^2 = 16^2 = 256\\
* 2^{10_d} &=& 2^{1010_b} = 2^8 \cdot 2^2 \\
* 2^1 &=& 2 \\
* 2^2 &=& (2^1)^2 = 4 \\
* 2^4 &=& (2^2)^2 = 16 \\
* 2^8 &=& (2^4)^2 = 256 \\
* \f}
* Hence to calculate 2^10 we only need to multiply \f$2^8\f$ and \f$2^2\f$
* skipping \f$2^1\f$ and \f$2^4\f$.
*
* Hence to calculate \f$2^{10}\f$, we only need to multiply \f$2^8\f$ and
* \f$2^2\f$, skipping \f$2^1\f$ and \f$2^4\f$.
*/

#include <iostream>
using namespace std;

/// Recursive function to calculate exponent in \f$O(\log(n))\f$ using binary
/// Recursive function to calculate exponent in O(log(n)) using binary
/// exponent.
int binExpo(int a, int b) {
if (b == 0) {
// Use long long for avoiding overflow.
long long binary_exponent_recursive(long long base, long long exponent) {
if (exponent == 0) {
return 1;
}
int res = binExpo(a, b / 2);
if (b % 2) {
return res * res * a;
long long half = binary_exponent_recursive(base, exponent / 2);
if (exponent % 2) {
return half * half * base;
} else {
return res * res;
return half * half;
}
}

/// Iterative function to calculate exponent in \f$O(\log(n))\f$ using binary
/// exponent.
int binExpo_alt(int a, int b) {
int res = 1;
while (b > 0) {
if (b % 2) {
res = res * a;
/// Use long long for avoiding Overflow
long long binary_exponent_iterative(long long base, long long exponent) {
long long res = 1;
while (exponent > 0) {
if (exponent % 2) {
res *= base;
}
a = a * a;
b /= 2;
base = base * base;
exponent >>= 1;
}
return res;
}

/// Main function
int main() {
int a, b;
/// Give two numbers a, b
std::cin >> a >> b;
if (a == 0 && b == 0) {
std::cout << "Math error" << std::endl;
} else if (b < 0) {
std::cout << "Exponent must be positive !!" << std::endl;
} else {
int resRecurse = binExpo(a, b);
/// int resIterate = binExpo_alt(a, b);
//@brief Self-test examples for verifying
void test() {
// Test 0
long long expected0 = 1024;
cout << "Test 0" << endl;
cout << "Input: base = 2 and exponent = 10" << endl;
cout << "Expected: " << expected0 << endl;
cout << "Recursive: " << binary_exponent_recursive(2, 10) << endl;
cout << "Iterative: " << binary_exponent_iterative(2, 10) << endl;
cout << endl;

/// Result of a^b (where '^' denotes exponentiation)
std::cout << resRecurse << std::endl;
/// std::cout << resIterate << std::endl;
}
// Test 1
long long expected1 = 2187;
cout << "Test 1" << endl;
cout << "Input: base = 3 and exponent = 7" << endl;
cout << "Expected: " << expected1 << endl;
cout << "Recursive: " << binary_exponent_recursive(3, 7) << endl;
cout << "Iterative: " << binary_exponent_iterative(3, 7) << endl;
cout << endl;

// Test 2
long long expected2 = 16777216;
cout << "Test 2" << endl;
cout << "Input: base = 4 and exponent = 12" << endl;
cout << "Expected: " << expected2 << endl;
cout << "Recursive: " << binary_exponent_recursive(4, 12) << endl;
cout << "Iterative: " << binary_exponent_iterative(4, 12) << endl;
cout << endl;

// Test 3
long long expected3 = 30517578125;
cout << "Test 3" << endl;
cout << "Input: base = 5 and exponent = 15" << endl;
cout << "Expected: " << expected3 << endl;
cout << "Recursive: " << binary_exponent_recursive(5, 15) << endl;
cout << "Iterative: " << binary_exponent_iterative(5, 15) << endl;
cout << endl;

// Test 4
long long expected4 = 3656158440062976;
cout << "Test 4" << endl;
cout << "Input: base = 6 and exponent = 20" << endl;
cout << "Expected: " << expected4 << endl;
cout << "Recursive: " << binary_exponent_recursive(6, 20) << endl;
cout << "Iterative: " << binary_exponent_iterative(6, 20) << endl;
cout << endl;
}

/// Main function
// returns 0 in case of no error.
int main() {
test(); // run self-test examples
return 0;
}
Loading