log2
MathComputes the base-2 logarithm of a positive 18-decimal fixed-point input via the change-of-base identity log₂(x) = ln(x) / ln(2).
Gas
391
Max rel. error
1.5e-14
Signature
function log2(uint256 x) internal pure returns (int256 y)Parameters
| Name | Type | Description |
|---|---|---|
| x | uint256 | Input in 18-decimal fixed-point format (1e18 = 1.0). Must satisfy x > 0. |
Returns
| Name | Type | Description |
|---|---|---|
| y | int256 | Result log₂(x) in 18-decimal fixed-point format. Signed — returns negative values for x < 1 (i.e. x < 1e18). |
Bounds
| Bound | Value |
|---|---|
| Input domain | Full uint256 domain except x == 0 (see Errors). Inherits ln's unbounded acceptance — no named upper or lower bound constants. |
Behavior
- Implemented as
ln(x) · 1e18 / 0.6931472…e18— a single multiply-and-divide on top ofln. - Reverts with
LnLowerBoundError()onx == 0, inherited from ln. - Returns 0 when
x == 1e18(i.e.log₂(1) = 0); negative whenx < 1e18; positive whenx > 1e18. - Precision inherits from ln; the change-of-base division adds a negligible ulp of rounding.
- Pure
internalfunction; no external calls or storage.
How it works
The change-of-base identity converts any logarithm into a single division by a constant:
log₂(x) = ln(x) / ln(2)
DeFiMath stores ln(2) as the 18-decimal constant 693147180559945309 (precision ~5e-19 vs. the true value). The implementation is one line:
y = ln(x) * 1e18 / 693147180559945309;
The multiplication by 1e18 before dividing keeps the result in 18-decimal fixed-point format. Total cost is one ln call (~375 gas) plus a 16-gas mul+div, hence the ~391 gas total.
Because the implementation is a thin wrapper over ln, every guarantee ln provides — domain (x > 0), precision, sign behavior — flows through directly. The only added error term is the rounding of ln(2) to 18 decimals, which is dwarfed by ln's own ~1e-14 error.
Errors
| Error | Trigger |
|---|---|
| LnLowerBoundError | x == 0 (inherited via the internal call to ln) |
Example
import "defimath-lib/contracts/math/Math.sol";
uint256 x = 8e18; // x = 8.0
int256 l2 = DeFiMath.log2(x); // l2 ≈ 3e18 (= log₂(8))
uint256 y = 0.5e18; // y = 0.5
int256 ly = DeFiMath.log2(y); // ly ≈ −1e18 (= log₂(0.5))