log2

Math

Computes 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

solidity
function log2(uint256 x) internal pure returns (int256 y)

Parameters

NameTypeDescription
xuint256Input in 18-decimal fixed-point format (1e18 = 1.0). Must satisfy x > 0.

Returns

NameTypeDescription
yint256Result log₂(x) in 18-decimal fixed-point format. Signed — returns negative values for x < 1 (i.e. x < 1e18).

Bounds

BoundValue
Input domainFull 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 of ln.
  • Reverts with LnLowerBoundError() on x == 0, inherited from ln.
  • Returns 0 when x == 1e18 (i.e. log₂(1) = 0); negative when x < 1e18; positive when x > 1e18.
  • Precision inherits from ln; the change-of-base division adds a negligible ulp of rounding.
  • Pure internal function; 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

ErrorTrigger
LnLowerBoundErrorx == 0 (inherited via the internal call to ln)

Example

solidity
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))