pow
MathComputes 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
function pow(uint256 x, int256 a) internal pure returns (uint256 y)Parameters
| Name | Type | Description |
|---|---|---|
| x | uint256 | Base in 18-decimal fixed-point format (1e18 = 1.0). When a == 0 the function fast-paths to 1 regardless of x. |
| a | int256 | Signed exponent in 18-decimal fixed-point format. Negative values give reciprocal powers. |
Returns
| Name | Type | Description |
|---|---|---|
| y | uint256 | x^a in 18-decimal fixed-point format. |
Bounds
| Bound | Value |
|---|---|
| MAX_POW_EXPONENT | 1e54 — 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_BOUND | 135.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 = 1for anyx, including the convention0^0 = 1. - Reverts with
LnLowerBoundError()whenx == 0anda ≠ 0(mathematically undefined). - Reverts with
ExpUpperBoundError()whena · ln(x)overflowsexp's upper bound (~135.3e18). - Returns
0whena · 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
| Error | Trigger |
|---|---|
| PowExponentOutOfBoundsError | |a| > MAX_POW_EXPONENT |
| LnLowerBoundError | x == 0 and a ≠ 0 (via the internal call to ln; the fast path x⁰ = 1 skips this for any x, including 0) |
| ExpUpperBoundError | a · ln(x) ≥ EXP_UPPER_BOUND (positive overflow only — via the internal call to exp; sufficiently negative exponents silently underflow to 0) |
Example
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)