Each established library does something better. This page says what, then puts the measurements side by side. Gas is the median per call on everyday inputs, inline on both sides.
Solady
What it does better: gas. Its expWad, lnWad and powWad are the cheapest WAD transcendentals there are, its code is small, and it runs on every EVM chain.
The answer: they are cheap because they stop short of the last wei. BlockulatorWad has Solady's names and is never off by a wei, at 5.5 times the gas on expWad and 4.3 times on lnWad. Its products and quotients cost 15 to 40 gas more than Solady's, and never revert where the result fits.
| Solady | BlockulatorWad | FP127 | |
|---|---|---|---|
| digits of precision at 1 | 18 | 18 | 38 |
| gas, mul | 86 | 107 | 267 |
| gas, exp | 430 | 2,357 | 2,716 |
| gas, ln | 556 | 2,415 | 1,944 |
| gas, pow | 1,275 | 4,762 | 3,317 |
| gas, sqrt | 393 | 388 | 469 |
| expWad results off by a wei | 48% | 0 | — |
| lnWad results off by a wei | 24% | 0 | — |
| powWad results off by a wei | 58% | 0 | — |
| daily compound interest: median digits after the last step | 14.8 | — | 34.8 |
| edge probes: median digits | 12 | — | 30 |
| edge probes: reverted | 3 | — | 9 |
| edge probes: went to zero | 27 | — | 3 |
| core ops formally proven | — | — | 17 of 17 |
PRBMath
What it does better: types. SD59x18 and UD60x18 are user-defined value types with operators, so a raw integer cannot be passed where a fixed-point value is meant.
The answer: FP19 and FP127 are typed the same way, and BlockulatorWad takes PRBMath's integers as they are. PRBMath is off by a wei more often than Solady, and BlockulatorWad costs less on every WAD function. PRBMath costs 2.9 times as much on ln and 2.1 times as much on pow.
| PRBMath SD | BlockulatorWad | FP127 | |
|---|---|---|---|
| digits of precision at 1 | 18 | 18 | 38 |
| gas, mul | 218 | 107 | 267 |
| gas, exp | 2,731 | 2,357 | 2,716 |
| gas, ln | 7,004 | 2,415 | 1,944 |
| gas, pow | 9,913 | 4,762 | 3,317 |
| gas, sqrt | 800 | 388 | 469 |
| expWad results off by a wei | 72% | 0 | — |
| lnWad results off by a wei | 98% | 0 | — |
| powWad results off by a wei | 64% | 0 | — |
| daily compound interest: median digits after the last step | 14.8 | — | 34.8 |
| edge probes: median digits | 9 | — | 30 |
| edge probes: reverted | 5 | — | 9 |
| edge probes: went to zero | 30 | — | 3 |
| core ops formally proven | — | — | 17 of 17 |
ABDK 64.64
What it does better: maturity and reach. ABDKMath64x64 is old, small and runs everywhere, and its mul and div cost less than FP127's.
The answer: FP127 is the same idea with 64 more fractional bits: 38 digits at 1 against 19, at lower gas on add, exp, ln and sqrt. On the edge calls it reverts less often and returns zero far less often. Its own limit is its range, ±1.7 × 1038.
| ABDK 64.64 | FP127 | |
|---|---|---|
| digits of precision at 1 | 19 | 38 |
| gas, mul | 171 | 267 |
| gas, exp | 3,380 | 2,716 |
| gas, ln | 7,080 | 1,944 |
| gas, pow | — | 3,317 |
| gas, sqrt | 828 | 469 |
| daily compound interest: median digits after the last step | 15.6 | 34.8 |
| edge probes: median digits | 9 | 30 |
| edge probes: reverted | 14 | 9 |
| edge probes: went to zero | 22 | 3 |
| core ops formally proven | — | 17 of 17 |
ABDKMathQuad (binary128)
What it does better: interoperability. Its values are IEEE 754 binary128, the same bits as quadruple precision off chain. Its sqrt costs less than FP19's.
The answer: FP19 has 237 bits of significand against 113, and costs less on add, mul, div, exp, ln and pow. Against FP127, binary128 keeps 34.0 digits at any size, and FP127 keeps 38.5 + log10|x|, which is more from |x| ≈ 3 × 10−5 up.
| ABDKMathQuad | FP19 | |
|---|---|---|
| digits of precision at 1 | 34 | 71 |
| gas, mul | 688 | 530 |
| gas, exp | 5,808 | 3,278 |
| gas, ln | 16,335 | 3,043 |
| gas, pow | 23,597 | 5,901 |
| gas, sqrt | 759 | 1,205 |
| daily compound interest: median digits after the last step | 29.9 | 67.4 |
| edge probes: median digits | 32 | 71 |
| edge probes: reverted | 0 | 0 |
| edge probes: went to zero | 0 | 0 |
| core ops formally proven | — | 18 of 24 |
Where Blockulator cannot go
- Chains without CLZ. FP19, FP127 and BlockulatorWad need the CLZ opcode (EIP-7939, the osaka EVM) and solc 0.8.31 or later, so they do not run on zkSync Era, Avalanche C-Chain or Polygon zkEVM (the list).
- The cheapest exp. Where a wei of error per call is acceptable, Solady is cheaper.
- Six FP19 ops without a proof. All 17 of FP127's core ops and 18 of FP19's 24 are proven for every input. FP19's
add,sub,sqrtand the threetoFixed18are fuzzed against their exact specs, not proven (proofs).