Placement Prep

Find the Power of a Number: C, C++, Java, Python

Three approaches to computing the power of a number: iterative O(n), fast O(log n), and library calls. Code in C, C++, Java, and Python with edge-case notes.

By FACE Prep Team 7 min read
algorithms c-plus-plus python java placement-prep recursion data-structures

Three approaches to computing the power of a number show up in placement coding rounds: an iterative O(n) loop, fast exponentiation at O(log n), and the built-in library call that returns a double.

Knowing all three, including when each one fails, covers every variant interviewers use on this problem. The legacy version of this article ran to 107 words with code placeholders. This rewrite builds the full picture.

Three Approaches at a Glance

ApproachTime complexitySpaceInteger-exact?
Library (pow, Math.pow, **)O(log n) internallyO(1)C/C++/Java: No. Python **: Yes
Iterative loopO(n)O(1)Yes, with long long
Fast exponentiationO(log n)O(1)Yes, with long long

The library call is fastest to write; the fast exponentiation is fastest to run for large exponents; the iterative loop is easiest to explain in an interview before optimising.

Library Calls: pow() and Math.pow()

All four languages have a built-in for power. The catch is that C, C++, and Java return a double, which can lose integer precision for large values.

According to cppreference, pow() in C is declared as double pow(double x, double y) in <math.h>. The C++ version lives in <cmath> with the same signature.

/* C */
#include <stdio.h>
#include <math.h>

int main(void) {
    printf("%.0f\n", pow(2, 10));  /* 1024 */
    return 0;
}
// C++
#include <iostream>
#include <cmath>

int main() {
    std::cout << static_cast<long long>(std::pow(2, 10)) << "\n"; // 1024
    return 0;
}
// Java
public class Power {
    public static void main(String[] args) {
        System.out.println((long) Math.pow(2, 10)); // 1024
    }
}

Python is the exception. As documented in the Python built-in functions reference, the two-argument pow(x, y) returns an int when both arguments are integers. The ** operator behaves the same way.

# Python
print(2 ** 10)          # 1024 -- exact integer
print(pow(2, 10))       # 1024 -- exact integer
import math
print(math.pow(2, 10))  # 1024.0 -- float, precision loss possible for large values

Precision note: A double has 53 bits of mantissa, so it can represent integers exactly only up to 2^53 (about 9 quadrillion). Beyond that, library calls may silently round. For placement problems with large bases, use the fast-exponentiation approach below.

Iterative O(n) Loop

The straightforward approach multiplies the base n times. For 2^10: multiply 1 by 2 ten times, arriving at 1024 in exactly 10 steps.

The critical detail is the type of result. Using int causes overflow when the answer passes 2^31 − 1, the maximum for a 32-bit signed integer. Two examples that make this concrete:

  • int max is 2^31 − 1; for base 46341 and exp 2, the result is 2147488281, which exceeds that limit and wraps to a wrong negative value on most compilers.
  • Inside fast exponentiation, base *= base squares base at every step, so overflow risk compounds quickly; long long is non-negotiable.

Use long long in C and C++, long in Java, and Python’s built-in arbitrary-precision int.

/* C -- iterative O(n) */
#include <stdio.h>

long long iterativePower(long long base, int exp) {
    long long result = 1;
    while (exp > 0) {
        result *= base;
        exp--;
    }
    return result;
}

int main(void) {
    printf("%lld\n", iterativePower(2, 10)); /* 1024 */
    return 0;
}
// C++ -- iterative O(n)
#include <iostream>

long long iterativePower(long long base, int exp) {
    long long result = 1;
    while (exp > 0) {
        result *= base;
        exp--;
    }
    return result;
}

int main() {
    std::cout << iterativePower(2, 10) << "\n"; // 1024
    return 0;
}
// Java -- iterative O(n)
public class Power {
    static long iterativePower(long base, int exp) {
        long result = 1;
        while (exp > 0) {
            result *= base;
            exp--;
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println(iterativePower(2, 10)); // 1024
    }
}
# Python -- iterative O(n)
def iterative_power(base, exp):
    result = 1
    while exp > 0:
        result *= base
        exp -= 1
    return result

print(iterative_power(2, 10))  # 1024

This works correctly and is easy to whiteboard. For large exponents such as n = 10^9, that many multiplications is too slow for any real-time evaluation. That is where fast exponentiation enters.

Fast Exponentiation: O(log n)

Fast exponentiation (also called binary exponentiation) cuts the number of loop iterations from n to roughly log2(n) by exploiting this identity:

  • If n is even: base^n = (base^(n/2))^2
  • If n is odd: base^n = base * (base^((n-1)/2))^2

Worked trace for 2^10

  • Start: result = 1, base = 2, exp = 10
  • Step 1: exp = 10 (even). Square base: base = 4. Halve exp: exp = 5.
  • Step 2: exp = 5 (odd). Multiply result: result = 1 * 4 = 4. Square base: base = 16. Halve exp: exp = 2.
  • Step 3: exp = 2 (even). Square base: base = 256. Halve exp: exp = 1.
  • Step 4: exp = 1 (odd). Multiply result: result = 4 * 256 = 1024. Halve exp: exp = 0.
  • Loop ends: result = 1024. Four iterations instead of ten.

Iterative fast exponentiation

/* C -- fast exponentiation O(log n) */
long long fastPower(long long base, int exp) {
    long long result = 1;
    while (exp > 0) {
        if (exp % 2 == 1) result *= base;
        base *= base;
        exp /= 2;
    }
    return result;
}
// C++ -- fast exponentiation O(log n)
long long fastPower(long long base, int exp) {
    long long result = 1;
    while (exp > 0) {
        if (exp % 2 == 1) result *= base;
        base *= base;
        exp /= 2;
    }
    return result;
}
// Java -- fast exponentiation O(log n)
static long fastPower(long base, int exp) {
    long result = 1;
    while (exp > 0) {
        if (exp % 2 == 1) result *= base;
        base *= base;
        exp /= 2;
    }
    return result;
}
# Python -- fast exponentiation O(log n)
def fast_power(base, exp):
    result = 1
    while exp > 0:
        if exp % 2 == 1:
            result *= base
        base *= base
        exp //= 2
    return result

Recursive divide-and-conquer

The recursive formulation maps directly to the mathematical identity. Each call computes half = fastPowerRec(base, exp / 2) once, then returns half * half for even exponents or base * half * half for odd exponents. Call depth is floor(log2(exp)) + 1, the same as the iterative version’s iteration count.

/* C -- recursive O(log n) */
long long fastPowerRec(long long base, int exp) {
    if (exp == 0) return 1;
    long long half = fastPowerRec(base, exp / 2);
    long long result = half * half;
    if (exp % 2 == 1) result *= base;
    return result;
}
# Python -- recursive O(log n)
def fast_power_rec(base, exp):
    if exp == 0:
        return 1
    half = fast_power_rec(base, exp // 2)
    result = half * half
    if exp % 2 == 1:
        result *= base
    return result

Both the iterative and recursive O(log n) versions produce identical results. Placement interviewers often ask for the recursive version first, then ask you to convert it to iterative. For the broader list of algorithm decisions that appear in coding interviews, see 20 most-asked data structures interview questions.

Edge Cases and Pitfalls

Four situations trip up standard implementations, and all four appear in placement tests.

Overflow with int

The long long fix above handles the straightforward overflow. Two subtler points:

  • In the fast-exponentiation loop, base *= base is the squaring step. After a few iterations, base grows extremely fast. Using int for base inside the loop overflows long before the exponent nears zero.
  • For competitive-programming variants where the answer is taken modulo a large prime, the standard pattern is (result * base) % MOD inside the loop. This keeps every intermediate value inside long long range.

Zero-base, zero-exponent: 0^0

By convention, 0^0 = 1 in all four languages. The iterative loop returns 1 when exp = 0 because result is initialised to 1 and the loop body never executes. The library functions agree: pow(0.0, 0.0) returns 1.0 in C/C++, Math.pow(0.0, 0.0) returns 1.0 in Java, and 0**0 is 1 in Python.

Negative exponents

The iterative loop as written returns 1 for any negative exponent, because the condition exp > 0 is false from the start. The correct approach for negative exponents is to compute the positive-exponent result and return its reciprocal as a double. Most placement questions constrain exp >= 0; if not, add a guard:

double powerWithNegative(double base, int exp) {
    if (exp < 0) return 1.0 / fastPower((long long)base, -exp);
    return (double)fastPower((long long)base, exp);
}

Precision loss in library calls

pow() and Math.pow() work in floating-point. A double holds 53 bits of mantissa, so it represents integers exactly only up to 2^53 (about 9 quadrillion). Beyond that, the returned value may differ from the true integer result: 2^53 + 1 and 2^53 + 2 both round to the same double. For placement problems with bases in the millions and exponents above 30, use the integer fast-exponentiation function rather than the library call.

The iterative single-pass structure here follows the same pattern as the find smallest and largest element in an array approach: initialise a result variable, iterate once, return. Recognising that pattern family speeds up whiteboarding for either problem.

The 10-to-4 reduction in multiplications for 2^10 above is the same reduce-operations instinct that shows up in how production AI systems batch and prune computations at inference time. TinkerLLM is where that instinct meets real LLM API calls: ₹299 for the launch month, no cohort commitment required.

Primary sources

Frequently asked questions

What is the time complexity of computing the power of a number?

The naive iterative loop runs in O(n) time — it multiplies the base n times. Fast exponentiation (binary exponentiation) runs in O(log n) by squaring the base and halving the exponent at each step.

Why does pow() return double instead of int in C and C++?

The C standard defines pow() to operate on doubles so it can handle fractional exponents and negative bases. It is declared in math.h (C) and cmath (C++). For integer results, cast the return value to long long, but be aware that doubles can only represent integers exactly up to 2^53.

What is 0 to the power of 0 in C, C++, Java, and Python?

All four languages return 1 for 0^0. The C and C++ standard says pow(0.0, 0.0) returns 1.0. Python's 0**0 and Java's Math.pow(0.0, 0.0) also return 1. The iterative loop also returns 1 because the result variable starts at 1 and the loop never runs when exp is 0.

How do I handle negative exponents without using the pow() library function?

A custom function needs a guard at the top: if exp is less than 0, compute the positive-exponent result and return 1.0 divided by it. The iterative loop as written skips the body when exp is 0 or negative, returning 1, which is wrong for negative exponents.

When should I use fast exponentiation instead of a simple loop?

Use fast exponentiation when the exponent is large (say, above 30) or when the problem asks for modular exponentiation, a common placement and competitive-programming pattern where the result is taken modulo a prime.

Does Python's ** operator handle large integers exactly?

Yes. Python integers have arbitrary precision. 2**100 returns the exact 31-digit integer. math.pow(2, 100) converts both arguments to float first, so it returns an approximate double. Use ** or the two-argument pow() for exact integer arithmetic in Python.

Build AI projects

A self-paced playground for building with LLMs.

TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.

Try TinkerLLM (₹299 launch)
Free AI Roadmap PDF