sqrt
MathComputes the principal square root of an 18-decimal fixed-point input.
Gas
245
Max rel. error
2.8e-16
Signature
function sqrt(uint256 x) internal pure returns (uint256 y)Parameters
| Name | Type | Description |
|---|---|---|
| x | uint256 | Input in 18-decimal fixed-point format (1e18 = 1.0). |
Returns
| Name | Type | Description |
|---|---|---|
| y | uint256 | Square root √x in 18-decimal fixed-point format. |
Bounds
| Bound | Value |
|---|---|
| SQRT_UPPER_BOUND | ⌊(2²⁵⁶ − 1) / 1e18⌋ + 1 ≈ 1.158e59 — the smallest input where the FP18 scaling step x · 1e18 would overflow uint256. x == 0 returns 0 without revert. |
Behavior
- Returns
0whenx == 0(no revert). - Reverts with
SqrtUpperBoundError()only at the input magnitude where the FP18 scaling step (x · 1e18) would overflowuint256— i.e.x ≥ ⌊(2²⁵⁶ − 1) / 1e18⌋ + 1 ≈ 1.158e59. - 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
Square root in fixed-point reduces to two well-known problems: getting a fast initial guess and converging quickly with Newton's iteration. DeFiMath does both in assembly. The CLZ opcode (introduced in EVM Osaka) gives us floor(log2(x)) for free, and from there an initial guess y₀ = 2^⌈bits/2⌉ lands within a factor of √2 (~1.41) of the true root — a one-bit error. Newton's iteration
y ← (y + x/y) / 2
then doubles the number of correct bits every step, so six iterations carry us from one correct bit to 64 — comfortably bit-exact at the 1e18 fixed-point scale.
To compute sqrt(v) · 1e18 we scale the input first: sqrt(x · 1e18) = sqrt(v · 1e36) = sqrt(v) · 1e18. So for inputs ≥ 1.0 we multiply by 1e18 once, run the iteration, and we're done. The input cap is set at exactly the boundary where this scaling multiplication would overflow uint256 — no earlier, so the function accepts the full precision-safe input range.
For inputs below 1.0 we invert instead of scaling: compute sqrt(1e54 / x), then divide 1e36 by the result. This preserves bit precision — a naive sqrt(x · 1e18) for tiny x would land in too few high-order bits and lose accuracy. The whole hot path stays in unchecked Yul assembly with no branches inside Newton — ~245 gas, the cheapest sqrt of any on-chain library we've measured.
Errors
| Error | Trigger |
|---|---|
| SqrtUpperBoundError | x ≥ SQRT_UPPER_BOUND |
Example
import "defimath-lib/contracts/math/Math.sol";
uint256 x = 2e18; // x = 2.0
uint256 y = DeFiMath.sqrt(x); // y ≈ 1.41421356e18