pow

Math

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

Gas

750

Max abs. 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). Must be > 0 unless a == 0.
aint256Signed exponent in 18-decimal fixed-point format. Negative values give reciprocal powers.

Returns

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

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 — ~750 gas total, roughly the sum of one ln (375 gas) and one exp (333 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.

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)