cbrt
MathComputes the real cube root of an 18-decimal fixed-point input.
Gas
368
Max abs. error
2.2e-16
Signature
function cbrt(uint256 x) internal pure returns (uint256 y)Parameters
| Name | Type | Description |
|---|---|---|
| x | uint256 | Input in 18-decimal fixed-point format (1e18 = 1.0). Must satisfy x < 7.5557863725914323e40 (true value < 2⁷⁶ ≈ 7.6e22). |
Returns
| Name | Type | Description |
|---|---|---|
| y | uint256 | Cube root ∛x in 18-decimal fixed-point format. |
Behavior
- Returns
0whenx == 0(no revert). - Reverts with
CbrtUpperBoundError()whenx ≥ 7.5557863725914323e40(true value ≥2⁷⁶). - Uses the
CLZopcode (Osaka) for a near-optimal initial guess; see EIP-7939. - Pure assembly hot path; no external calls or storage.
How it works
Cube root follows the same recipe as sqrt — a CLZ-derived initial guess plus Newton's iteration — but with a twist that makes the implementation noticeably simpler. The cube-root Newton update is
y ← (2y + x/y²) / 3
which still has quadratic convergence: each step roughly doubles the number of correct bits. The CLZ-derived initial guess y₀ = 2^⌈bits/3⌉ lands within a factor of ∛2 (~1.26) of the true root — slightly tighter than sqrt's √2 start. Six iterations are enough to reach bit-exact precision at the 1e18 fixed-point scale.
The nice property of cube root is that it scales symmetrically. To compute cbrt(v) · 1e18 we multiply the input by 1e36 once: cbrt(x · 1e36) = cbrt(v · 1e54) = cbrt(v) · 1e18. The same formula works for all x > 0 — no separate small-input branch, no inversion trick. That symmetry is why sqrt has two branches and cbrt has one.
The x · 1e36 scaling is what sets the input cap: keeping it inside uint256 means x < 2²⁵⁶ / 1e36 ≈ 2⁷⁶ in true value (~7.6e22) — still enormous for any realistic DeFi quantity. The whole hot path stays in unchecked Yul assembly: ~368 gas.
Example
import "defimath-lib/contracts/math/Math.sol";
uint256 x = 8e18; // x = 8.0
uint256 y = DeFiMath.cbrt(x); // y = 2e18