The ladder measures a slope. This measures the cliffs: ln within a per-second rate of one, exp(−42), a probability of 10−18, a year of seconds as an exponent, the normal tail where an option's price lives. A cell has its correct digits, or says why there are none: zero (below the format's floor), range (the argument does not fit the word), or the name of the error it reverts with. An empty cell is an op the library does not offer. BL127's own walls are here too: exp past ±88, the word at 1.7 × 1038, erfc past 9.3.
BL127's and BL19's deployed contracts checked live on Sepolia: 276 results at block 12,017,760, 0 mismatches. The other libraries' results reproduce locally with make ladder. 2026-10-29, runner 0xad11E2a6…. Re-run: uv run scripts/ladder/liveedges.py
How this was measured
- digits
- digits = floor(-log10 |v - t| / |t|), capped at 100 (reported as exact); errUlps is the signed error in units of the representation's last place (none for the floats).
- gas
- gas is measured inside the adapter around the op, after the adapter and the BL127 object are warm. The BL127 (deployed) form includes the staticcall; the others are internal calls.
- live
- EdgeRunner.run(op, form, args) on Sepolia evaluates any cell with one eth_call and returns (ok, raw, reason, gas); scripts/ladder/liveedges.py sends every probe's encoded arguments and compares the raw word bit for bit.
- range
- RANGE means the argument does not fit the representation at all (above 2^127 for BL127, 2^63 for 64.64, 2^128 as a bit pattern for binary128; BL19 holds every probe) and nothing was called.
- reproduce
- make edges regenerates edges.json and edges.md from test/ladder/Edges.t.sol and this script; make edges-check fails CI when the committed dataset differs.
- reverted
- A revert is recorded with its selector and name. Unsupported means the library has no way to compute the op (the accrual libraries have no general ops; only BL127 and BL19 have the secondary Lambert branch; the libraries without erf, erfc or normCdf run the same series and continued fraction through their own ops instead, so those cells are not Unsupported).
- truth
- Every probe is one op evaluated once. The truth is mpmath at 200 decimal digits from the exact arguments; truthFormat is the same op from the arguments as the representation holds them (floored on a grid, nearest for binary128), so digitsFormat measures the op alone and digits what a caller sees.
- zero
- A cell is marked zero when the library returned 0 and the truth is not 0: the result fell below the representation's floor. On an 18-decimal grid that is anything below 1e-18; on BL127's, below 2^-128.
- versions
- Generated 2026-10-28; aave aave-v3-origin@8305565ae342 (MathUtils, transcribed), abdk v3.2, balancer balancer-v3-monorepo@2b9ce4b1b8ad (LogExpMath.sol, vendored), bl127 6c2eeaf, euler evk-periphery@af436991e135 (IRMAdaptiveCurve, ExpLib, transcribed), forge 1.7.1, fraxlend fraxlend@2bed49d4dcc6 (VariableInterestRate V2, transcribed), huff sepolia:0xfae694D0c2c44181791F838c54Ed64C3151FfE30@11857616, maker dss pot.sol rpow via solady v0.1.26, morpho morpho-blue@8e26ca6a8dbc (MathLib, transcribed), openzeppelin openzeppelin-contracts v5.7.0 (Math, SignedMath, vendored), prb-math v4.2.0, snekmate v0.1.2 (math module, vyper 0.4.3), solady v0.1.26, solmate solmate@89365b8 (no tag: v6 predates SignedWadMath), uniswap v4-core v4.0.0 (FullMath, vendored).
ln(x)
The logarithm near one is where a per-second rate lives: ln(1 + r) for r = 1e-9 has eight digits on an 18-decimal grid.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
ln(1+1e-6) | 0.0000009999… | 65 | 28 | 34 | 13 | 12 | 12 | 11 | 11 | 12 | 12 | — | — | — | — | — | — | — |
ln(1+1e-9) | 0.0000000009… | 62 | 25 | 30 | 10 | 9 | 9 | 8 | 8 | 9 | 9 | — | — | — | — | — | — | — |
ln(1+1e-12) | 0.0000000000… | 59 | 22 | 26 | 7 | 6 | 6 | 5 | 5 | 6 | 5 | — | — | — | — | — | — | — |
ln(1+1e-15) | 9.9999999999… | 56 | 19 | 24 | 4 | 15 | 15 | 2 | 2 | 15 | 3 | — | — | — | — | — | — | — |
ln(1+1e-18) | 9.9999999999… | 53 | 16 | 21 | 1 | 18 | 18 | zero | zero | 18 | zero | — | — | — | — | — | — | — |
ln(1-1e-12) | -0.000000000… | 59 | 24 | 26 | 6 | 12 | 12 | 5 | revert | 12 | 12 | — | — | — | — | — | — | — |
ln(1e-18) | -41.44653167… | 71 | 33 | 22 | 3 | 19 | 19 | 19 | revert | 19 | 20 | — | — | — | — | — | — | — |
ln(1e-30) | -69.07755278… | 71 | 33 | 10 | revert | revert | revert | revert | revert | zero | revert | — | — | — | — | — | — | — |
ln(1e30) | 69.077552789… | 71 | 33 | 41 | range | 20 | 20 | 18 | 18 | 20 | 20 | — | — | — | — | — | — | — |
ln(1e38) | 87.498233533… | 71 | 33 | 40 | range | 20 | 20 | 18 | 18 | 20 | 20 | — | — | — | — | — | — | — |
| fewest digits | 53 | 16 | 10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | — | — | — | — | |
Revert reasons
- PRB UD: PRBMath_UD60x18_Log_InputTooSmall
- 64.64: bare revert (require without a reason, or out of gas)
- Solady: Solady LnWadUndefined()
- Solmate: Error(string): a require with a message (Solmate's wadLn and snekmate's wad_ln below zero)
- PRB SD: PRBMath_SD59x18_Log_InputTooSmall
- Balancer: Balancer OutOfBounds()
exp(x)
exp below -42 is zero on an 18-decimal grid and has one digit at -40: every probability, discount or decay smaller than 1e-18 is gone.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
exp(-1e-12) | 0.9999999999… | 71 | 34 | 39 | 18 | 24 | 24 | 18 | revert | 24 | 24 | — | — | — | — | — | — | — |
exp(-20) | 0.0000000020… | 71 | 32 | 31 | 10 | 9 | 9 | 9 | revert | 9 | 9 | — | — | — | — | — | — | — |
exp(-30) | 9.3576229688… | 71 | 32 | 26 | 6 | 5 | 5 | 5 | revert | 5 | 5 | — | — | — | — | — | — | — |
exp(-40) | 4.2483542552… | 71 | 32 | 21 | 2 | 1 | 1 | 1 | revert | 1 | 1 | — | — | — | — | — | — | — |
exp(-41) | 1.5628821893… | 71 | 32 | 21 | 1 | 0 | 0 | 0 | revert | 0 | 0 | — | — | — | — | — | — | — |
exp(-42) | 5.7495222642… | 71 | 32 | 21 | 1 | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
exp(-43) | 2.1151310375… | 71 | 32 | 21 | 0 | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
exp(-60) | 8.7565107626… | 71 | 32 | 13 | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
exp(-88) | 6.0546018954… | 71 | 31 | 1 | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
exp(-89) | 2.2273635617… | 71 | 31 | 0 | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
exp(-100) | 3.7200759760… | 71 | 31 | zero | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
exp(40) | 235385266837… | 71 | 32 | 57 | 19 | 20 | 20 | 16 | 16 | 20 | 21 | — | — | — | — | — | — | — |
exp(43) | 472783946822… | 71 | 32 | 58 | 21 | 21 | 21 | 16 | 16 | 21 | 20 | — | — | — | — | — | — | — |
exp(44) | 128516001143… | 71 | 32 | 57 | revert | 20 | 20 | 16 | 16 | 20 | 20 | — | — | — | — | — | — | — |
exp(60) | 114200738981… | 71 | 32 | 65 | revert | 20 | 20 | 16 | 16 | 20 | 20 | — | — | — | — | — | — | — |
exp(88) | 165163625499… | 71 | 31 | 77 | revert | 20 | 20 | 16 | 16 | 20 | 20 | — | — | — | — | — | — | — |
exp(89) | 448961281917… | 71 | 31 | revert | revert | 20 | 20 | 16 | 16 | 20 | 20 | — | — | — | — | — | — | — |
exp(100) | 2.6881171418… | 71 | 31 | revert | revert | 21 | 21 | 16 | 16 | 21 | 21 | — | — | — | — | — | — | — |
exp(130) | 2.8726495508… | 71 | 31 | revert | revert | 20 | 20 | 16 | 16 | 20 | 21 | — | — | — | — | — | — | — |
exp(135) | 4.2633899483… | 71 | 31 | revert | revert | 20 | 20 | revert | revert | 20 | revert | — | — | — | — | — | — | — |
exp(136) | 1.1589095424… | 71 | 31 | revert | revert | revert | revert | revert | revert | revert | revert | — | — | — | — | — | — | — |
| fewest digits | 71 | 31 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | — | — | — | — | |
Revert reasons
- PRB UD: ParamOutOfRange(uint256): the value does not fit the representation
- Balancer: Balancer InvalidExponent()
- 64.64: bare revert (require without a reason, or out of gas)
- BL127: Overflow()
- PRB SD: PRBMath_SD59x18_Exp_InputTooBig
- PRB UD: PRBMath_UD60x18_Exp_InputTooBig
- Solady: Solady ExpOverflow()
- Solmate: Error(string): a require with a message (Solmate's wadLn and snekmate's wad_ln below zero)
- snek: Error(string): a require with a message (Solmate's wadLn and snekmate's wad_ln below zero)
sqrt(x)
The root of a tiny number: sqrt(1e-20) is 1e-10, which the grid holds, but 1e-20 itself is zero on it.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
sqrt(1e-6) | 0.001 | 71 | 34 | 33 | 13 | exact | exact | exact | exact | exact | exact | exact | — | — | — | — | — | — |
sqrt(1e-12) | 0.000001 | 71 | 34 | 27 | 8 | exact | exact | exact | exact | exact | exact | exact | — | — | — | — | — | — |
sqrt(1e-18) | 0.000000001 | 71 | 34 | 21 | 1 | exact | exact | exact | exact | exact | exact | exact | — | — | — | — | — | — |
sqrt(1e-20) | 0.0000000001 | 71 | 34 | 19 | zero | zero | zero | zero | zero | zero | zero | zero | — | — | — | — | — | — |
sqrt(1e-30) | 1.0e-15 | 71 | 34 | 8 | zero | zero | zero | zero | zero | zero | zero | zero | — | — | — | — | — | — |
sqrt(1e30) | 100000000000… | exact | exact | exact | range | exact | exact | exact | exact | exact | 18 | exact | — | — | — | — | — | — |
sqrt(1e36) | 100000000000… | exact | exact | exact | range | exact | exact | exact | exact | exact | 18 | exact | — | — | — | — | — | — |
sqrt(1e38) | 100000000000… | exact | exact | exact | range | exact | exact | exact | exact | exact | 17 | exact | — | — | — | — | — | — |
sqrt(1e40) | 100000000000… | exact | exact | range | range | exact | exact | exact | exact | exact | 18 | exact | — | — | — | — | — | — |
sqrt(1e50) | 100000000000… | exact | exact | range | range | exact | revert | revert | revert | revert | 18 | revert | — | range | range | — | — | — |
| fewest digits | 71 | 34 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | 0 | 0 | — | — | — | |
Revert reasons
- Solmate: Panic (checked arithmetic overflow or division by zero)
- PRB SD: PRBMath_SD59x18_Sqrt_Overflow
- PRB UD: PRBMath_UD60x18_Sqrt_Overflow
- snek: bare revert (require without a reason, or out of gas)
- OZ: Panic (checked arithmetic overflow or division by zero)
pow(x, y)
A base near one to a large power: per-second rates over years, and Uniswap's tick range 1.0001^(+-887272).
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
pow(1+0.05/31536000, 31536000) | 1.0512710963… | 63 | 27 | 31 | 11 | 10 | 10 | 9 | 9 | 10 | 11 | — | — | — | — | — | — | — |
pow(1+0.001/31536000, 31536000) | 1.0010005001… | 63 | 26 | 31 | 11 | 10 | 10 | 9 | 9 | 10 | 10 | — | — | — | — | — | — | — |
pow(1+0.05/31536000, 315360000) | 1.6487212700… | 62 | 26 | 30 | 10 | 9 | 9 | 8 | 8 | 9 | 10 | — | — | — | — | — | — | — |
pow(1+0.05/31536000/12, 31536000*12) | 1.0512710963… | 62 | 25 | 30 | 10 | 10 | 10 | 8 | 8 | 10 | 9 | — | — | — | — | — | — | — |
pow(1.0001, 887272) | 340256786836… | 65 | 29 | revert | revert | 12 | 12 | 11 | 11 | 12 | 17 | — | — | — | — | — | — | — |
pow(1.0001, -887272) | 2.9389568075… | 65 | 29 | 4 | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
pow(0.999999, 1000000) | 0.3678792572… | 65 | 28 | 32 | 13 | 12 | 12 | 11 | 11 | 12 | 18 | — | — | — | — | — | — | — |
pow(2, 0.5) | 1.4142135623… | 71 | 33 | 39 | 18 | 17 | 17 | 18 | 18 | 17 | 17 | — | — | — | — | — | — | — |
pow(10, -18) | 1.0e-18 | 71 | 31 | 20 | 1 | exact | exact | exact | revert | exact | revert | — | — | — | — | — | — | — |
pow(1e-9, 0.5) | 0.0000316227… | 71 | 32 | 29 | 10 | 9 | 9 | 9 | 9 | 9 | 9 | — | — | — | — | — | — | — |
pow(1e-18, 0.5) | 0.000000001 | 71 | 32 | 21 | 1 | exact | exact | exact | exact | exact | exact | — | — | — | — | — | — | — |
| fewest digits | 62 | 25 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | — | — | — | — | |
Revert reasons
- BL127: Overflow()
- 64.64: bare revert (require without a reason, or out of gas)
- PRB UD: ParamOutOfRange(uint256): the value does not fit the representation
- Balancer: Negative(): a negative value where the library is unsigned (Balancer pow, PRBMath UD60x18, the WAD roots)
mul(a, b)
Tiny times tiny: a fee on a fee, a unit price times a unit size, below 1e-18 is zero.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
mul(1e-9, 1e-9) | 1.0e-18 | 71 | 33 | 20 | 1 | zero | zero | zero | zero | zero | zero | zero | zero | — | — | — | — | — |
mul(1e-10, 1e-10) | 1.0e-20 | 71 | 34 | 18 | zero | zero | zero | zero | zero | zero | zero | zero | zero | — | — | — | — | — |
mul(1e-12, 1e-8) | 1.0e-20 | 71 | 34 | 18 | zero | zero | zero | zero | zero | zero | zero | zero | zero | — | — | — | — | — |
mul(1e19, 1e19) | 100000000000… | exact | exact | exact | range | exact | exact | exact | exact | exact | exact | exact | exact | — | — | — | — | — |
mul(1e20, 1e20) | 100000000000… | exact | exact | revert | range | exact | exact | exact | exact | exact | exact | exact | exact | — | — | — | — | — |
| fewest digits | 71 | 33 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | — | — | |
Revert reasons
- BL127: Overflow()
div(a, b)
Small over large, and one over tiny.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
div(1, 3) | 0.3333333333… | 71 | 34 | 38 | 19 | 17 | 17 | 17 | 17 | 17 | 17 | 17 | 17 | — | — | — | — | — |
div(1e-12, 1e9) | 1.0e-21 | 71 | 34 | 17 | zero | zero | zero | zero | zero | zero | zero | zero | zero | — | — | — | — | — |
div(1e-9, 1e12) | 1.0e-21 | 71 | 33 | 17 | zero | zero | zero | zero | zero | zero | zero | zero | zero | — | — | — | — | — |
div(1e30, 1e-9) | 100000000000… | exact | exact | revert | range | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | — | — | — | — | — |
div(1, 1e-30) | 100000000000… | exact | exact | 8 | revert | revert | revert | revert | revert | revert | revert | revert | revert | — | — | — | — | — |
| fewest digits | 71 | 33 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | — | — | |
Revert reasons
- BL127: Overflow()
- 64.64: bare revert (require without a reason, or out of gas)
- Solady: Solady SDivWadFailed()
- Solmate: bare revert (require without a reason, or out of gas)
- PRB SD: Panic (checked arithmetic overflow or division by zero)
- PRB UD: Panic (checked arithmetic overflow or division by zero)
- snek: Error(string): a require with a message (Solmate's wadLn and snekmate's wad_ln below zero)
- Balancer: Panic (checked arithmetic overflow or division by zero)
- OZ: Panic (checked arithmetic overflow or division by zero)
- Uniswap: bare revert (require without a reason, or out of gas)
W0(x)
The principal Lambert branch near its branch point -1/e, where the slope is infinite; only Solady has it among the others.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
lambertW0(-1/e+1e-6) | -0.997670166… | 69 | — | 35 | — | 15 | — | — | revert | — | — | — | — | — | — | — | — | — |
lambertW0(-1/e+1e-9) | -0.999926268… | 67 | — | 34 | — | 13 | — | — | revert | — | — | — | — | — | — | — | — | — |
lambertW0(-1/e+1e-12) | -0.999997668… | 65 | — | 32 | — | 12 | — | — | revert | — | — | — | — | — | — | — | — | — |
lambertW0(-1/e+1e-15) | -0.999999926… | 64 | — | 31 | — | 10 | — | — | revert | — | — | — | — | — | — | — | — | — |
lambertW0(-1/e+1e-18) | -0.999999997… | 62 | — | 29 | — | 8 | — | — | revert | — | — | — | — | — | — | — | — | — |
lambertW0(-1e-18) | -1.000000000… | 71 | — | 20 | — | 17 | — | — | revert | — | — | — | — | — | — | — | — | — |
lambertW0(1e-18) | 9.9999999999… | 71 | — | 21 | — | 18 | — | — | — | — | — | — | — | — | — | — | — | — |
lambertW0(1e30) | 64.904633770… | 71 | — | 41 | range | 20 | — | — | — | — | — | — | — | — | — | — | — | — |
lambertW0(1e38) | 83.078448213… | 71 | — | 40 | range | 20 | — | — | — | — | — | — | — | — | — | — | — | — |
| fewest digits | 62 | — | 20 | 0 | 8 | — | — | 0 | — | — | — | — | — | — | — | — | — | |
Revert reasons
- PRB UD: ParamOutOfRange(uint256): the value does not fit the representation
W-1(x)
The secondary branch, toward zero from below; BL127 only.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
lambertWm1(-1/e+1e-9) | -1.000073734… | 67 | — | 34 | — | — | — | — | revert | — | — | — | — | — | — | — | — | — |
lambertWm1(-1e-10) | -26.29523881… | 71 | — | 30 | — | — | — | — | revert | — | — | — | — | — | — | — | — | — |
lambertWm1(-1e-30) | -73.37311031… | 71 | — | 11 | — | — | — | — | revert | — | — | — | — | — | — | — | — | — |
| fewest digits | 67 | — | 11 | — | — | — | — | 0 | — | — | — | — | — | — | — | — | — | |
Revert reasons
- PRB UD: ParamOutOfRange(uint256): the value does not fit the representation
log1p(x)
ln(1 + x) as an op: the libraries without it compute ln(1 + x), and 1 + x is where x loses its digits.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
log1p(1e-6) | 0.0000009999… | 71 | 28 | 34 | 13 | 12 | 12 | 11 | 11 | 12 | 12 | — | — | — | — | — | — | — |
log1p(1e-9) | 0.0000000009… | 71 | 25 | 30 | 10 | 8 | 8 | 8 | 8 | 8 | 8 | — | — | — | — | — | — | — |
log1p(1e-12) | 0.0000000000… | 71 | 22 | 26 | 7 | 12 | 12 | 5 | 5 | 12 | 6 | — | — | — | — | — | — | — |
log1p(1e-15) | 9.9999999999… | 71 | 18 | 24 | 4 | 15 | 15 | 2 | 2 | 15 | 3 | — | — | — | — | — | — | — |
log1p(1e-18) | 9.9999999999… | 71 | 15 | 21 | 1 | 18 | 18 | zero | zero | 18 | zero | — | — | — | — | — | — | — |
log1p(1e-20) | 9.9999999999… | 71 | 14 | 18 | zero | zero | zero | zero | zero | zero | zero | — | — | — | — | — | — | — |
log1p(1e-30) | 9.9999999999… | 71 | 4 | 8 | zero | zero | zero | zero | zero | zero | zero | — | — | — | — | — | — | — |
log1p(-1e-9) | -0.000000001… | 71 | 25 | 30 | 10 | 9 | 9 | 8 | revert | 9 | 9 | — | — | — | — | — | — | — |
log1p(1e6) | 13.815511557… | 71 | 33 | 40 | 20 | 19 | 19 | 18 | 18 | 19 | 19 | — | — | — | — | — | — | — |
| fewest digits | 71 | 4 | 8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | — | — | — | — | |
Revert reasons
- PRB UD: ParamOutOfRange(uint256): the value does not fit the representation
expm1(x)
e^x - 1 as an op: the libraries without it compute exp(x) - 1 and the one cancels the digits.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
expm1(1e-6) | 0.0000010000… | 71 | 27 | 33 | 13 | 12 | 12 | 11 | 11 | 12 | 12 | — | — | — | — | — | — | — |
expm1(1e-9) | 0.0000000010… | 71 | 24 | 29 | 9 | 8 | 8 | 8 | 8 | 8 | 8 | — | — | — | — | — | — | — |
expm1(1e-12) | 0.0000000000… | 71 | 21 | 26 | 7 | 12 | 12 | 5 | 5 | 12 | 12 | — | — | — | — | — | — | — |
expm1(1e-15) | 1.0000000000… | 71 | 18 | 23 | 4 | 15 | 15 | 2 | 2 | 15 | 15 | — | — | — | — | — | — | — |
expm1(1e-18) | 1.0000000000… | 71 | 15 | 20 | 1 | 18 | 18 | zero | zero | 18 | 18 | — | — | — | — | — | — | — |
expm1(1e-20) | 1.0000000000… | 71 | 14 | 18 | zero | zero | zero | zero | zero | zero | zero | — | — | — | — | — | — | — |
expm1(-1e-9) | -0.000000000… | 71 | 25 | 30 | 10 | 9 | 9 | 9 | revert | 9 | 9 | — | — | — | — | — | — | — |
expm1(-40) | -0.999999999… | 71 | 34 | 38 | 19 | 18 | 18 | 18 | revert | 18 | 18 | — | — | — | — | — | — | — |
expm1(-88) | -0.999999999… | 71 | 34 | 39 | 38 | 38 | 38 | 38 | revert | 38 | revert | — | — | — | — | — | — | — |
expm1(20) | 485165194.40… | 71 | 32 | 47 | 19 | 19 | 19 | 17 | 17 | 19 | 21 | — | — | — | — | — | — | — |
| fewest digits | 71 | 14 | 18 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | — | — | — | — | |
Revert reasons
- PRB UD: ParamOutOfRange(uint256): the value does not fit the representation
- Balancer: Balancer InvalidExponent()
compound(r, n)
(1 + r)^n for an integer n: per-second rates over years. BL127 and Maker take an exact integer power; the rest exp(n ln(1 + r)).
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
compound(0.05/31536000, 31536000) | 1.0512710963… | 71 | 26 | 31 | 11 | 12 | 12 | 10 | 10 | 10 | 11 | — | — | 19 | — | — | — | — |
compound(0.05/31536000, 315360000) | 1.6487212700… | 71 | 25 | 30 | 10 | 11 | 11 | 9 | 9 | 9 | 10 | — | — | 18 | — | — | — | — |
compound(0.001/31536000, 31536000) | 1.0010005001… | 71 | 26 | 31 | 12 | 10 | 10 | 10 | 10 | 10 | 10 | — | — | 19 | — | — | — | — |
compound(0.1/365, 365) | 1.1051557816… | 71 | 31 | 36 | 17 | 17 | 17 | 15 | 15 | 15 | 16 | — | — | 24 | — | — | — | — |
compound(1e-12, 1000000000) | 1.0010005001… | 71 | 25 | 29 | 11 | 12 | 12 | 12 | 12 | 15 | 18 | — | — | 22 | — | — | — | — |
compound(-0.5, 10) | 0.0009765625 | exact | 32 | exact | exact | exact | exact | exact | revert | 14 | exact | — | — | revert | — | — | — | — |
compound(0.000000001, 10000000) | 1.0100501670… | 71 | 27 | 31 | 12 | 10 | 10 | 10 | 10 | 10 | 10 | — | — | 19 | — | — | — | — |
| fewest digits | 71 | 25 | 29 | 10 | 10 | 10 | 9 | 0 | 9 | 10 | — | — | 0 | — | — | — | — | |
Revert reasons
- PRB UD: ParamOutOfRange(uint256): the value does not fit the representation
- Maker: ParamOutOfRange(uint256): the value does not fit the representation
powu(x, n)
An integer power. Solady's rpow, PRBMath's powu, ABDK's pow and Maker's rpow square at the format's precision; BL127 on a 256-bit mantissa.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
powu(2, 10) | 1024.0 | exact | 32 | exact | exact | exact | exact | exact | exact | 17 | 17 | — | — | exact | — | — | — | — |
powu(1.0001, 887272) | 340256786836… | 65 | 29 | revert | revert | 13 | 13 | 12 | 12 | 12 | 17 | — | — | revert | — | — | — | — |
powu(1.0001, -887272) | 2.9389568075… | 65 | 29 | 4 | revert | zero | zero | zero | zero | zero | zero | — | — | — | — | — | — | — |
powu(0.999999, 1000000) | 0.3678792572… | 65 | 28 | 32 | 13 | 14 | 14 | 13 | 13 | 12 | 18 | — | — | 23 | — | — | — | — |
powu(1+0.05/31536000, 31536000) | 1.0512710963… | 63 | 27 | 31 | 11 | 12 | 12 | 10 | 10 | 10 | 11 | — | — | 19 | — | — | — | — |
powu(10, 38) | 100000000000… | exact | 31 | exact | revert | exact | exact | exact | exact | 16 | 16 | — | — | revert | — | — | — | — |
powu(3, -5) | 0.0041152263… | 71 | 32 | 36 | 17 | 15 | 15 | 15 | 15 | 15 | 15 | — | — | — | — | — | — | — |
powu(1.1, 100) | 13780.612339… | 69 | 32 | 36 | 17 | 19 | 19 | 19 | 19 | 17 | 15 | — | — | 29 | — | — | — | — |
| fewest digits | 63 | 27 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | 0 | — | — | — | — | |
Revert reasons
- BL127: Overflow()
- 64.64: bare revert (require without a reason, or out of gas)
- Maker: Solady RPowOverflow() (Maker's rpow)
erf(x)
The error function; the libraries without it run the same series and continued fraction through their own ops.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
erf(1e-10) | 0.0000000001… | 71 | 33 | 28 | 9 | 8 | 8 | 8 | 8 | 8 | 8 | — | — | — | — | — | — | — |
erf(0.5) | 0.5204998778… | 71 | 32 | 39 | 17 | 16 | 16 | 16 | revert | 16 | 16 | — | — | — | — | — | — | — |
erf(1) | 0.8427007929… | 71 | 32 | 39 | 17 | 16 | 16 | 16 | revert | 16 | 16 | — | — | — | — | — | — | — |
erf(3) | 0.9999779095… | 71 | 32 | 39 | 15 | 14 | 14 | 14 | revert | 14 | 14 | — | — | — | — | — | — | — |
erf(4) | 0.9999999845… | 71 | 32 | 39 | 12 | 11 | 11 | 11 | revert | 11 | 11 | — | — | — | — | — | — | — |
erf(5) | 0.9999999999… | 71 | 34 | 38 | 19 | 18 | 18 | 18 | revert | 18 | 18 | — | — | — | — | — | — | — |
erf(6) | 0.9999999999… | 71 | 34 | 39 | 19 | 18 | 18 | 18 | revert | 18 | 18 | — | — | — | — | — | — | — |
erf(8) | 0.9999999999… | 71 | 34 | 39 | 28 | 28 | 28 | 28 | revert | 28 | revert | — | — | — | — | — | — | — |
erf(9) | 0.9999999999… | 71 | 34 | 39 | 36 | 36 | 36 | 36 | revert | 36 | revert | — | — | — | — | — | — | — |
| fewest digits | 71 | 32 | 28 | 9 | 8 | 8 | 8 | 0 | 8 | 0 | — | — | — | — | — | — | — | |
Revert reasons
- PRB UD: Negative(): a negative value where the library is unsigned (Balancer pow, PRBMath UD60x18, the WAD roots)
- Balancer: Balancer InvalidExponent()
erfc(x)
The tail of the normal distribution: erfc(6) is 2e-17, erfc(9.3) one ULP of BL127, zero on an 18-decimal grid from about 6.4.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
erfc(1) | 0.1572992070… | 71 | 31 | 38 | 17 | 16 | 16 | 16 | revert | 16 | 15 | — | — | — | — | — | — | — |
erfc(3) | 0.0000220904… | 71 | 27 | 34 | 10 | 9 | 9 | 9 | revert | 9 | 9 | — | — | — | — | — | — | — |
erfc(4) | 0.0000000154… | 71 | 24 | 31 | 4 | 3 | 3 | 3 | revert | 3 | 3 | — | — | — | — | — | — | — |
erfc(5) | 0.0000000000… | 71 | 32 | 27 | 7 | 6 | 6 | 6 | revert | 6 | 6 | — | — | — | — | — | — | — |
erfc(6) | 2.1519736712… | 71 | 32 | 23 | 2 | 1 | 1 | 1 | revert | 1 | 1 | — | — | — | — | — | — | — |
erfc(7) | 4.1838256077… | 71 | 32 | 16 | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
erfc(8) | 1.1224297172… | 71 | 32 | 10 | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
erfc(9) | 4.1370317465… | 71 | 32 | 2 | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
erfc(9.3) | 1.6532441840… | 69 | 34 | 0 | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
erfc(10) | 2.0884875837… | 71 | 31 | zero | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
| fewest digits | 69 | 24 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | — | — | — | — | |
Revert reasons
- PRB UD: Negative(): a negative value where the library is unsigned (Balancer pow, PRBMath UD60x18, the WAD roots)
- Balancer: Balancer InvalidExponent()
normCdf(x)
N(d) of Black-Scholes: zero on an 18-decimal grid from d = -8.3, two ULPs of BL127 at -13.
| Floating point | Fixed point | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| probe | truth | BL19 | Quad | BL127 | 64.64 | Solady | Solmate | PRB SD | PRB UD | snek | Balancer | OZ | Uniswap | Maker | Aave | Morpho | Frax | Euler |
normCdf(1e-12) | 0.5000000000… | 71 | 34 | 38 | 19 | 18 | 18 | 18 | 18 | 18 | 18 | — | — | — | — | — | — | — |
normCdf(-1) | 0.1586552539… | 71 | 32 | 38 | 17 | 16 | 16 | 16 | revert | 16 | 16 | — | — | — | — | — | — | — |
normCdf(-3) | 0.0013498980… | 71 | 29 | 35 | 14 | 13 | 13 | 13 | revert | 13 | 13 | — | — | — | — | — | — | — |
normCdf(-5) | 0.0000002866… | 71 | 26 | 32 | 8 | 6 | 6 | 6 | revert | 6 | 6 | — | — | — | — | — | — | — |
normCdf(-6) | 0.0000000009… | 71 | 32 | 30 | 10 | 8 | 8 | 8 | revert | 8 | 8 | — | — | — | — | — | — | — |
normCdf(-8) | 6.2209605742… | 71 | 31 | 24 | 4 | 3 | 3 | 3 | revert | 3 | 3 | — | — | — | — | — | — | — |
normCdf(-8.3) | 5.2055697448… | 69 | 32 | 23 | 3 | 2 | 2 | 2 | revert | 2 | 2 | — | — | — | — | — | — | — |
normCdf(-9) | 1.1285884059… | 71 | 31 | 21 | 1 | zero | zero | zero | revert | zero | zero | — | — | — | — | — | — | — |
normCdf(-10) | 7.6198530241… | 71 | 32 | 15 | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
normCdf(-13) | 6.1171643995… | 71 | 31 | 1 | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
normCdf(-14) | 7.7935368191… | 71 | 31 | zero | zero | zero | zero | zero | revert | zero | revert | — | — | — | — | — | — | — |
normCdf(5) | 0.9999997133… | 71 | 32 | 39 | 14 | 12 | 12 | 12 | revert | 12 | 12 | — | — | — | — | — | — | — |
| fewest digits | 69 | 26 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | — | — | — | — | |
Revert reasons
- PRB UD: ParamOutOfRange(uint256): the value does not fit the representation
- Balancer: Balancer InvalidExponent()
- PRB UD: Negative(): a negative value where the library is unsigned (Balancer pow, PRBMath UD60x18, the WAD roots)
A cell is the correct significant digits against the exact value; hover it for the value and its error in ULP. zero: below the format's floor; range: the argument does not fit the word; any other red word is a revert, named by its error (hover for the full reason). A — is an op the library does not offer. BL19's digits are shown to 71, its precision: a 72 or 73 is where the truth happens to sit near the grid. The last row is each library's fewest digits on the op, with a zero, revert or range counted as 0. Full dataset: edges.json. Regenerate with make edges.