pow

Math

Computes the power function x^a for an 18-decimal fixed-point base and signed exponent.

Gas

748

Max rel. error

5.2e-14

Signature

solidity
function pow(uint256 x, int256 a) internal pure returns (uint256 y)

Parameters

NameTypeDescription
xuint256Base in 18-decimal fixed-point format (1e18 = 1.0). When a == 0 the function fast-paths to 1 regardless of x.
aint256Signed exponent in 18-decimal fixed-point format. Negative values give reciprocal powers.

Returns

NameTypeDescription
yuint256x^a in 18-decimal fixed-point format.

Bounds

BoundValue
EXP_UPPER_BOUND135.305999…e18 — inherited from exp, applied to the composed exponent a · ln(x). At a · ln(x) ≥ EXP_UPPER_BOUND the function reverts.
EXP_LOWER_BOUND−41.446531…e18 — also inherited from exp. At a · ln(x) ≤ EXP_LOWER_BOUND the inner exp(…) silently returns 0, so pow returns 0 — graceful underflow, no revert.

Behavior

  • Fast path: x^0 = 1 for any x, including the convention 0^0 = 1.
  • Reverts with LnLowerBoundError() when x == 0 and a ≠ 0 (mathematically undefined).
  • Reverts with ExpUpperBoundError() when a · ln(x) overflows exp's upper bound (~135.3e18).
  • Returns 0 when a · ln(x) ≤ −41.45e18 — a graceful underflow inherited from exp.
  • Pure assembly hot path via ln and exp; no external calls or storage.

How it works

The cleanest power implementation in fixed-point uses the textbook identity

x^a = exp(a · ln(x))

DeFiMath just composes its ln and exp — no separate Taylor series, no special handling of integer exponents, no per-case branching. The composition inherits both functions' bounds and precision automatically, and means pow doesn't have to be re-tuned every time ln or exp get a gas tweak.

One fast path: x^0 = 1 (which also covers 0^0 = 1 by convention) short-circuits before either expensive call. Everything else flows through ln, multiplies by a, then through exp — ~748 gas total, roughly the sum of one ln (375 gas) and one exp (331 gas).

The composition picks up CLZ savings for free. ln uses the CLZ opcode for range reduction (see the CLZ writeup), exp uses a Padé approximant on a tiny reduced range. Both stay in inline assembly. The cost of pow is exactly the cost of its parts — predictable and stable.

Errors

ErrorTrigger
LnLowerBoundErrorx == 0 and a ≠ 0 (via the internal call to ln; the fast path x⁰ = 1 skips this for any x, including 0)
ExpUpperBoundErrora · ln(x) ≥ EXP_UPPER_BOUND (positive overflow only — via the internal call to exp; sufficiently negative exponents silently underflow to 0)

Example

solidity
import "defimath-lib/contracts/math/Math.sol";

uint256 x = 2e18;                // x = 2.0
int256  a = 10e18;               // a = 10
uint256 y = DeFiMath.pow(x, a);  // y = 1024e18 (2^10)