Mathematics7 min readExamples run on PHP 8.5.10

pow()

Learn how PHP 8.4 pow() raises a base to an exponent, when it returns int or float, and how to avoid NAN, overflow and zero-exponent pitfalls.

Signature

pow(mixed $num, mixed $exponent): int|float|object

Purpose

pow() raises a base to an exponent. It is the function form of the ** operator, so pow(2, 8) and 2 ** 8 express the same calculation. Use it for squares, cubes, growth formulas, scaling by powers of ten and any other place where a number is multiplied by itself a given number of times.

Signature

Parameters

  • $num is the base, the number being raised.
  • $exponent is the power to raise it to.

Neither parameter has a default value, so both are required. Both are declared as mixed because extensions can supply their own number types. In everyday code you pass ints and floats.

Return value

If both arguments are non-negative integers and the result fits in an integer, pow() returns an int. In every other case it returns a float. That includes negative exponents, fractional exponents, float inputs and integer results too large for the platform integer. Extensions such as GMP may override the operation and return an object instead.

The function does not throw for ordinary numeric input. Mathematically undefined results come back as special float values. For example, a negative base with a non-integer exponent gives NAN.

Example 1: integer and float results

The first example shows that the result type follows the inputs.

Example
<?php
var_dump(pow(2, 8));
var_dump(pow(2, 0.5) > 1.41);
var_dump(pow(-2, 3));
Output
int(256)
bool(true)
int(-8)

The whole-number calls stay integers. A fractional exponent is a root, so the result is a float and is compared here instead of printed in full.

Example 2: negative and fractional exponents

A negative exponent means a reciprocal, and an exponent of 0.5 means a square root. The values below are encoded as JSON so the types are visible: floats keep a decimal part, while pow(0, 0) stays an integer 1.

Example
<?php
$values = [
    pow(10, -1),
    pow(2, -2),
    pow(9, 0.5),
    pow(2.5, 2),
    pow(0, 0),
];
echo json_encode($values), PHP_EOL;
Output
[0.1,0.25,3,6.25,1]

Example 3: growth, overflow and NAN

A typical use is compound growth: a balance of 1000 growing by 10 percent for two periods. The example also shows an integer result that still fits and one that overflows into a float, and a call that produces NAN.

Example
<?php
$balance = 1000 * pow(1.1, 2);
echo round($balance, 2), PHP_EOL;
var_dump(pow(2, 62));
var_dump(pow(2, 63));
var_dump(is_nan(pow(-1, 5.5)));
Output
1210
int(4611686018427387904)
float(9.223372036854776E+18)
bool(true)

On a 64-bit build, 2 to the power 62 is still an integer. 2 to the power 63 exceeds the largest integer, so PHP silently switches to a float and precision is lost.

Edge cases

  • Zero exponent: any base raised to 0, including 0 itself, gives 1.
  • Zero to a negative exponent: this means dividing by zero. As of PHP 8.4.0, raising 0 to a negative exponent is deprecated, so avoid it and guard the input. If you need IEEE 754 behavior, the related function fpow() is the documented alternative.
  • Negative base: an integer exponent works normally, and the sign depends on whether the exponent is even or odd. A fractional exponent such as 5.5 has no real result and returns NAN.
  • Large results: integer overflow turns into a float. Float overflow can produce INF.
  • Operator precedence: the ** operator binds tighter than unary minus, so -2 ** 2 is -4, while pow(-2, 2) is 4. The operator is also right-associative, so 2 ** 3 ** 2 means 2 ** 9.

Common mistakes

  1. Expecting an int every time. Code that checks is_int() on the result breaks as soon as an exponent is negative or the value is large. Cast deliberately if you need an integer, and check the range first.
  2. Trusting loose input. The manual warns that this function converts all input to a number, even non-scalar values, which can give odd results. Validate user data before passing it in.
  3. Comparing floats with ==. Results such as pow(1.1, 2) carry binary rounding error. Use round() or a tolerance.
  4. Ignoring NAN. NAN is not equal to anything, including itself. Test it with is_nan().
  5. Using it for exact big numbers. Native ints and floats are limited. For arbitrary precision, use bcpow() or gmp_pow() instead.
  6. Mixing up powers and roots. sqrt() is clearer than pow($x, 0.5) for square roots, and exp() is for powers of e.
  • Exponentiation operator **: the operator form of the same calculation.
  • fpow(): raises a number to a power according to IEEE 754.
  • exp(): calculates e raised to a power.
  • sqrt(): square root.
  • bcpow(): arbitrary precision power on numeric strings.
  • gmp_pow(): power for GMP integers.

Recap

pow($num, $exponent) returns an int when both inputs are non-negative integers and the result fits, otherwise a float. Expect NAN for a negative base with a fractional exponent, a float on overflow, and a deprecation for zero raised to a negative exponent in PHP 8.4. Validate inputs, compare floats carefully, and choose arbitrary precision tools when exact large values matter.

Tested examples

Integer and float results
<?php
var_dump(pow(2, 8));
var_dump(pow(2, 0.5) > 1.41);
var_dump(pow(-2, 3));
Output
int(256)
bool(true)
int(-8)
Negative and fractional exponents
<?php
$values = [
    pow(10, -1),
    pow(2, -2),
    pow(9, 0.5),
    pow(2.5, 2),
    pow(0, 0),
];
echo json_encode($values), PHP_EOL;
Output
[0.1,0.25,3,6.25,1]
Growth, overflow and NAN
<?php
$balance = 1000 * pow(1.1, 2);
echo round($balance, 2), PHP_EOL;
var_dump(pow(2, 62));
var_dump(pow(2, 63));
var_dump(is_nan(pow(-1, 5.5)));
Output
1210
int(4611686018427387904)
float(9.223372036854776E+18)
bool(true)