pow

Math

Computes x raised to the power a in 18-decimal fixed-point.

Avg. gas

761

Max abs. error

1.0e-14

Max rel. error

1.0e-12

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
MAX_POW_EXPONENT1e54 — direct input bound on |a|. Beyond this the internal a · ln(x) multiplication (kept inside unchecked for gas) could wrap int256 silently, so the function rejects up-front. Astronomically larger than any realistic financial exponent (real-value 10³⁶).
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 — ~761 gas total: one ln (390 gas), one exp (289 gas), the MAX_POW_EXPONENT input check, and the mul-and-divide that joins them.

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
PowExponentOutOfBoundsError|a| > MAX_POW_EXPONENT
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 = Math.pow(x, a);  // y = 1024e18 (2^10)