Each scenario is N identical steps run through each library in its native representation, for several inputs, against the same loop in exact arithmetic. It is measured twice: against the exact inputs, which is what a protocol sees, and against the inputs as each format rounds them, which isolates the library's arithmetic. The chart is the summary over all inputs; the table is the reference input in full, and every cell of it can be re-run on Sepolia. "How this was measured" defines every number.
How this was measured
- truth
- For every scenario, input and N the same loop is run in exact real arithmetic with mpmath at 200 decimal digits (scripts/ladder/ladder.py), from the exact rational parameters in scenarios.json. Closed forms are used where the loop has one (compounding, the cumulative product, the geometric mean, the round trip); the bonding curve, the amortising loan and the Black-Scholes chain are stepped.
- rounding
- Each library receives the parameters floored into its own representation (2^-128, 2^-64 or 10^-18 units; scripts/ladder/inputs.json). truthFormat is the exact loop started from those floored parameters, so digitsFormat measures the library's arithmetic alone, while digits measures what a protocol sees: the format's rounding of the inputs plus the arithmetic.
- digits
- digits = floor(-log10 |v - t| / |t|), the number of correct leading significant digits by relative error, capped at 60, which is reported as exact. It is not a string comparison: a value can be correct to 36 digits while its 37th printed digit happens to agree with the truth, or while a carry makes the printed prefix differ earlier.
- agree
- agree is the count of leading significant digits of the printed value (42 significant digits) that are literally equal to the printed truth. The demo page colours the rest of the value with it. It is a reading aid, not a measurement: a carry across 0.999… / 1.000… gives 0.
- gas
- gasTotal is measured inside the adapter around the scenario function (the parameter reads and the loop), after the runner has warmed the adapter and the FP127 object, so the call into the adapter and the ABI decoding are excluded. The FP127 (deployed) form includes one staticcall per op; FP127Lib and the other libraries are internal calls. gasPerStep = gasTotal / N. Reverted cells carry no gas.
- live
- LadderRunner.run(scenario, form, n, p) on Sepolia executes any cell with one eth_call and returns (ok, raw, reason, gasPerStep, gasTotal). The demo's verify button sends the cell's floored parameters p and compares the returned raw word with the committed one bit for bit (or the revert selector for a reverted cell). liveMaxN is the largest N per form the public RPC completed within its gas limit, measured by scripts/ladder/livecap.py.
- reproduce
- make ladder regenerates ladder.json and ladder.md from the Foundry harness (test/ladder/Ladder.t.sol) and this script; make ladder-check fails CI when the committed dataset differs. Versions of every library and of forge are recorded in the dataset. Generated 2026-10-06; versions: abdk v3.2, forge forge Version: 1.7.1, fp127 f8e9bb1, huff sepolia:0xfae694D0c2c44181791F838c54Ed64C3151FfE30@11857616, prb-math v4.2.0, solady v0.1.26.
Daily compound interest
Step: b = b * (1 + r). Result: balance after N days.
Per-block or per-day accrual in every lending protocol: one mul per step, N steps.
Over all 10 inputs
| N | FP127 | FP127Lib | ABDK | Solady | PRBMath | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 38 | 40 | 38 | 40 | 19 | 40 | 18 | 40 | 18 | 40 |
| 2 | 38 | 40 | 38 | 40 | 19 | 23 | 18 | 22 | 18 | 22 |
| 5 | 38 | 40 | 38 | 40 | 18.5 | 22.5 | 18 | 21 | 18 | 21 |
| 10 | 37 | 40 | 37 | 40 | 18 | 22 | 17 | 21 | 17 | 21 |
| 20 | 37 | 40 | 37 | 40 | 18 | 22 | 17 | 21 | 17 | 21 |
| 50 | 37 | 40 | 37 | 40 | 17.5 | 21 | 17 | 20 | 17 | 20 |
| 100 | 36 | 40 | 36 | 40 | 17 | 21 | 16 | 20 | 16 | 20 |
| 365 | 36 | 40 | 36 | 40 | 16.5 | 21 | 16 | 19 | 16 | 19 |
| 1000 | 35 | 39 | 35 | 39 | 16 | 20 | 15 | 19 | 15 | 19 |
| 10000 | 34 | 39 | 34 | 39 | 15 | 19.5 | 14 | 18 | 14 | 18 |
Median (min–max) correct digits over the inputs, capped at 40; "rev" counts inputs that reverted at that N and are excluded.
The inputs and the ops
| input | parameters | why |
|---|---|---|
| reference | principal = 10000, rate = 0.1/365 | $10,000 at 10% APR, the headline cell |
| tiny-low | principal = 1, rate = 0.01/365 | one unit at 1%: the integer part is small, the fraction carries everything |
| tiny-high | principal = 1, rate = 0.5/365 | one unit at 50% |
| mid-1pct | principal = 10000, rate = 0.01/365 | a slow rate: the per-step factor is close to 1 |
| mid-5pct | principal = 10000, rate = 0.05/365 | a typical lending rate |
| mid-50pct | principal = 10000, rate = 0.5/365 | a high rate: the balance grows 150x by N = 10,000 |
| large | principal = 1000000, rate = 0.1/365 | a million-unit position |
| huge | principal = 100000000, rate = 0.1/365 | a hundred-million-unit pool |
| huge-high | principal = 100000000, rate = 0.5/365 | the largest balance the ladder reaches, near 10^14 |
| fraction | principal = 0.001, rate = 0.1/365 | a sub-unit balance: leading zeros in WAD |
Library calls per step: FP127 mul; FP127Lib mul; ABDK mul; Solady sMulWad; PRBMath mul. Parameters reach each adapter floored into its representation (ladder-inputs.json).
The reference input in full: principal = 10000, rate = 0.1/365
Each cell: the value with the digits that agree with the truth in ink and the rest in red; below it, correct digits against the exact truth, against the format-rounded truth, the signed error in units of the last place, and gas per step.
| N | truth | FP127 (deployed, staticcall) | FP127Lib (inline) | ABDKMath64x64 | Solady FixedPointMathLib | PRBMath SD59x18 |
|---|---|---|---|---|---|---|
| 1 | 10002.7397260273972602739726027397260273973 | 10002.7397260273972602739726027397260273831 |
10002.7397260273972602739726027397260273831 |
10002.7397260273972600785191700012433102529 |
10002.73972602739726 |
10002.73972602739726 |
| 2 | 10005.4802026646650403452805404391067742541 | 10005.4802026646650403452805404391067742258 |
10005.4802026646650403452805404391067742258 |
10005.4802026646650399542451230494588543252 |
10005.480202664665039797 |
10005.480202664665039797 |
| 5 | 10013.7061382924386210524857642965155424808 | 10013.7061382924386210524857642965155424101 |
10013.7061382924386210524857642965155424101 |
10013.7061382924386200740608440784562560566 |
10013.706138292438619679 |
10013.706138292438619679 |
| 10 | 10027.4310624075663873328585783270357249574 | 10027.4310624075663873328585783270357248157 |
10027.4310624075663873328585783270357248157 |
10027.4310624075663853733086060271428863189 |
10027.431062407566384582 |
10027.431062407566384582 |
| 20 | 10054.9373711336135548503369243222913751056 | 10054.9373711336135548503369243222913748213 |
10054.9373711336135548503369243222913748213 |
10054.937371133613550920398935217825453492 |
10054.937371133613549333 |
10054.937371133613549333 |
| 50 | 10137.9098421416552959332725454243516547326 | 10137.909842141655295933272545424351654016 |
10137.909842141655295933272545424351654016 |
10137.9098421416552860271844023476450757926 |
10137.909842141655282022 |
10137.909842141655282022 |
| 100 | 10277.721596739264220164675884991779643531 | 10277.7215967392642201646758849917796420782 |
10277.7215967392642201646758849917796420782 |
10277.7215967392642000792805576092625585716 |
10277.721596739264191958 |
10277.721596739264191958 |
| 365 | 11051.5578161626437393801159668054461177946 | 11051.5578161626437393801159668054461120925 |
11051.5578161626437393801159668054461120925 |
11051.5578161626436605492209384882240641446 |
11051.557816162643628692 |
11051.557816162643628692 |
| 1000 | 13151.2942008121758666272801482974151894245 | 13151.2942008121758666272801482974151708344 |
13151.2942008121758666272801482974151708344 |
13151.294200812175609621539323218497585799 |
13151.294200812175505839 |
13151.294200812175505839 |
| 10000 | 154769.34069144112806190764064318746174622 | 154769.340691441128061907640643187459558592 |
154769.340691441128061907640643187459558592 |
154769.340691441097818583337575315539424992 |
154769.340691441085644663 |
154769.340691441085644663 |
Compound interest in one pow
Step: b0 * (1 + r)^N. Result: the same balance, computed with one real-exponent pow.
The clever way to skip the loop. pow is exp(N ln(1+r)) in every library, so its precision is bounded by ln and exp, and the error grows with N without any loop.
Over all 10 inputs
| N | FP127 | FP127Lib | ABDK | Solady | PRBMath | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 38 | 40 | 38 | 40 | 19 | 19 | 17 | 18 | 18 | 40 |
| 2 | 38 | 38 | 38 | 38 | 18 | 18.5 | 17 | 17 | 16 | 16 |
| 5 | 38 | 38 | 38 | 38 | 18 | 18 | 17 | 17 | 16 | 16 |
| 10 | 38 | 38 | 38 | 38 | 18 | 18 | 17 | 17 | 16 | 16 |
| 20 | 37 | 37 | 37 | 37 | 17 | 18 | 16 | 16 | 15 | 15 |
| 50 | 37 | 37 | 37 | 37 | 17 | 17 | 16 | 16 | 15 | 15 |
| 100 | 36 | 36.5 | 36 | 36.5 | 17 | 17 | 16 | 16 | 15 | 15 |
| 365 | 36 | 36 | 36 | 36 | 16 | 16.5 | 15 | 15 | 14 | 14 |
| 1000 | 35 | 36 | 35 | 36 | 16 | 16 | 15 | 15 | 14 | 14 |
| 10000 | 34.5 | 35 | 34.5 | 35 | 15 | 15 | 14 | 14 | 13 | 13 |
Median (min–max) correct digits over the inputs, capped at 40; "rev" counts inputs that reverted at that N and are excluded.
The inputs and the ops
| input | parameters | why |
|---|---|---|
| reference | principal = 10000, rate = 0.1/365 | $10,000 at 10% APR, the headline cell |
| tiny-low | principal = 1, rate = 0.01/365 | one unit at 1%: the integer part is small, the fraction carries everything |
| tiny-high | principal = 1, rate = 0.5/365 | one unit at 50% |
| mid-1pct | principal = 10000, rate = 0.01/365 | a slow rate: the per-step factor is close to 1 |
| mid-5pct | principal = 10000, rate = 0.05/365 | a typical lending rate |
| mid-50pct | principal = 10000, rate = 0.5/365 | a high rate: the balance grows 150x by N = 10,000 |
| large | principal = 1000000, rate = 0.1/365 | a million-unit position |
| huge | principal = 100000000, rate = 0.1/365 | a hundred-million-unit pool |
| huge-high | principal = 100000000, rate = 0.5/365 | the largest balance the ladder reaches, near 10^14 |
| fraction | principal = 0.001, rate = 0.1/365 | a sub-unit balance: leading zeros in WAD |
Library calls per step: FP127 pow, mul; FP127Lib pow, mul; ABDK exp, mul, ln (pow = exp(y ln x)); Solady powWad, sMulWad; PRBMath pow, mul. Parameters reach each adapter floored into its representation (ladder-inputs.json).
The reference input in full: principal = 10000, rate = 0.1/365
Each cell: the value with the digits that agree with the truth in ink and the rest in red; below it, correct digits against the exact truth, against the format-rounded truth, the signed error in units of the last place, and gas per step.
| N | truth | FP127 (deployed, staticcall) | FP127Lib (inline) | ABDKMath64x64 | Solady FixedPointMathLib | PRBMath SD59x18 |
|---|---|---|---|---|---|---|
| 1 | 10002.7397260273972602739726027397260273973 | 10002.7397260273972602739726027397260273831 |
10002.7397260273972602739726027397260273831 |
10002.7397260273972595364180837584910932492 |
10002.73972602739725 |
10002.73972602739726 |
| 2 | 10005.4802026646650403452805404391067742541 | 10005.4802026646650403452805404391067742095 |
10005.4802026646650403452805404391067742095 |
10005.4802026646650383841577469645756082173 |
10005.48020266466503 |
10005.48020266466484 |
| 5 | 10013.7061382924386210524857642965155424808 | 10013.7061382924386210524857642965155424512 |
10013.7061382924386210524857642965155424512 |
10013.7061382924386174642777946885985329573 |
10013.70613829243859 |
10013.70613829243812 |
| 10 | 10027.4310624075663873328585783270357249574 | 10027.4310624075663873328585783270357249083 |
10027.4310624075663873328585783270357249083 |
10027.4310624075663802559285620041862330254 |
10027.43106240756634 |
10027.4310624075654 |
| 20 | 10054.9373711336135548503369243222913751056 | 10054.9373711336135548503369243222913750323 |
10054.9373711336135548503369243222913750323 |
10054.9373711336135415973444540149728254619 |
10054.93737113361346 |
10054.93737113361157 |
| 50 | 10137.9098421416552959332725454243516547326 | 10137.9098421416552959332725454243516545332 |
10137.9098421416552959332725454243516545332 |
10137.9098421416552629724383560727574149496 |
10137.90984214165505 |
10137.90984214165031 |
| 100 | 10277.721596739264220164675884991779643531 | 10277.7215967392642201646758849917796431089 |
10277.7215967392642201646758849917796431089 |
10277.7215967392641536234942911676171206636 |
10277.72159673926373 |
10277.72159673925412 |
| 365 | 11051.5578161626437393801159668054461177946 | 11051.5578161626437393801159668054461161677 |
11051.5578161626437393801159668054461161677 |
11051.5578161626434791067405405406987028982 |
11051.55781616264184 |
11051.55781616260411 |
| 1000 | 13151.2942008121758666272801482974151894245 | 13151.294200812175866627280148297415184062 |
13151.294200812175866627280148297415184062 |
13151.294200812175020048715168297093214278 |
13151.29420081216967 |
13151.29420081204668 |
| 10000 | 154769.34069144112806190764064318746174622 | 154769.340691441128061907640643187461116794 |
154769.340691441128061907640643187461116794 |
154769.340691441028485565711836358104847022 |
154769.34069144039984 |
154769.34069142592578 |
Square-root bonding curve
Step: cost += sqrt(s); s += 1. Result: total cost of N unit buys.
Bonding curves price each token at a root of the supply; the sum of N floors is where the digits go.
Over all 7 inputs
| N | FP127 | FP127Lib | ABDK | Solady | PRBMath | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 40 | 40 | 40 | 40 | 23 | 23 | 22 | 22 | 22 | 22 |
| 2 | 40 | 40 | 40 | 40 | 20 | 20 | 19 | 19 | 19 | 19 |
| 5 | 40 | 40 | 40 | 40 | 21 | 21 | 19 | 19 | 19 | 19 |
| 10 | 40 | 40 | 40 | 40 | 20 | 20 | 19 | 19 | 19 | 19 |
| 20 | 40 | 40 | 40 | 40 | 21 | 21 | 19 | 19 | 19 | 19 |
| 50 | 40 | 40 | 40 | 40 | 21 | 21 | 19 | 19 | 19 | 19 |
| 100 | 40 | 40 | 40 | 40 | 21 | 21 | 19 | 19 | 19 | 19 |
| 365 | 40 | 40 | 40 | 40 | 21 | 21 | 19 | 19 | 19 | 19 |
| 1000 | 40 | 40 | 40 | 40 | 21 | 21 | 19 | 19 | 19 | 19 |
| 10000 | 40 | 40 | 40 | 40 | 21 | 21 | 20 | 20 | 20 | 20 |
Median (min–max) correct digits over the inputs, capped at 40; "rev" counts inputs that reverted at that N and are excluded.
The inputs and the ops
| input | parameters | why |
|---|---|---|
| reference | supply = 1000, unit = 1 | a thousand tokens out, unit buys |
| from-one | supply = 1, unit = 1 | the curve from its first token |
| half-units | supply = 1000, unit = 0.5 | buys that are not integers |
| deep | supply = 1000000, unit = 1 | a million out: sqrt is large, the sum is huge |
| micro | supply = 1, unit = 0.001 | thousandth-unit buys from the start |
| very-deep | supply = 1000000000, unit = 1000 | a billion out in thousand-token lots |
| small-steps | supply = 10, unit = 0.01 | hundredth-unit buys from ten |
Library calls per step: FP127 sqrt, add; FP127Lib sqrt, add; ABDK sqrt, add; Solady sqrtWad, add; PRBMath sqrt, add. Parameters reach each adapter floored into its representation (ladder-inputs.json).
The reference input in full: supply = 1000, unit = 1
Each cell: the value with the digits that agree with the truth in ink and the rest in red; below it, correct digits against the exact truth, against the format-rounded truth, the signed error in units of the last place, and gas per step.
| N | truth | FP127 (deployed, staticcall) | FP127Lib (inline) | ABDKMath64x64 | Solady FixedPointMathLib | PRBMath SD59x18 |
|---|---|---|---|---|---|---|
| 1 | 31.6227766016837933199889354443271853371956 | 31.6227766016837933199889354443271853371954 |
31.6227766016837933199889354443271853371954 |
31.6227766016837933199458594846209535944581 |
31.622776601683793319 |
31.622776601683793319 |
| 2 | 63.2613606407965424630952270291281684242756 | 63.2613606407965424630952270291281684242738 |
63.2613606407965424630952270291281684242738 |
63.2613606407965424630393536098438289627666 |
63.261360640796542462 |
63.261360640796542462 |
| 5 | 158.271878503221320234300570350652186729491 | 158.271878503221320234300570350652186729484 |
158.271878503221320234300570350652186729484 |
158.271878503221320234157706852151648035942 |
158.271878503221320232 |
158.271878503221320232 |
| 10 | 316.938155912380578582534163023823506795788 | 316.938155912380578582534163023823506795773 |
316.938155912380578582534163023823506795773 |
316.938155912380578582243466356782590764851 |
316.938155912380578577 |
316.938155912380578577 |
| 20 | 635.450002940208176168731350846033723899844 | 635.450002940208176168731350846033723899815 |
635.450002940208176168731350846033723899815 |
635.450002940208176168183050458448946073986 |
635.450002940208176158 |
635.450002940208176158 |
| 50 | 1600.35088143869734634844272805794430858922 | 1600.35088143869734634844272805794430858915 |
1600.35088143869734634844272805794430858915 |
1600.35088143869734634698901928895331536751 |
1600.350881438697346324 |
1600.350881438697346324 |
| 100 | 3239.29226451438240670571916593133108873454 | 3239.2922645143824067057191659313310887344 |
3239.2922645143824067057191659313310887344 |
3239.29226451438240670297179918390995112532 |
3239.292264514382406656 |
3239.292264514382406656 |
| 365 | 12536.2620049472952153455284521422191448628 | 12536.2620049472952153455284521422191448622 |
12536.2620049472952153455284521422191448622 |
12536.2620049472952153357631008279149398277 |
12536.262004947295215169 |
12536.262004947295215169 |
| 1000 | 38540.0786548103528040149168003592993412283 | 38540.0786548103528040149168003592993412268 |
38540.0786548103528040149168003592993412268 |
38540.0786548103528039883598592385549608252 |
38540.078654810352803518 |
38540.078654810352803518 |
| 10000 | 748008.007615874676777707582886478609217336 | 748008.007615874676777707582886478609217321 |
748008.007615874676777707582886478609217321 |
748008.007615874676777438468874836807742668 |
748008.007615874676772695 |
748008.007615874676772695 |
exp(ln(x)) round trip
Step: x = exp(ln(x)). Result: x after N round trips; the answer is the input.
Isolates transcendental error. Every step should be the identity; what remains is the library's ln and exp error, compounded.
Over all 10 inputs
| N | FP127 | FP127Lib | ABDK | Solady | PRBMath | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 38 | 39 | 38 | 39 | 19 | 19 | 18 | 18 | 17 | 17 |
| 2 | 38 | 39 | 38 | 39 | 18 | 18 | 17 | 17 | 16 | 16 |
| 5 | 38 | 39 | 38 | 39 | 18 | 18 | 17 | 17 | 16 | 16 |
| 10 | 38 | 39 | 38 | 39 | 17.5 | 17.5 | 17 | 17 | 16 | 16 |
| 20 | 38 | 39 | 38 | 39 | 17 | 17 | 16 | 16 | 15 | 15 |
| 50 | 38 | 39 | 38 | 39 | 17 | 17 | 16 | 16 | 15 | 15 |
| 100 | 38 | 39 | 38 | 39 | 17 | 17 | 16 | 16 | 15 | 15 |
| 365 | 38 | 39 | 38 | 39 | 16 | 16 | 15 | 15 | 14 | 14 |
| 1000 | 38 | 39 | 38 | 39 | 16 | 16 | 15 | 15 | 14 | 14 |
| 10000 | 38 | 39 | 38 | 39 | 15 | 15 | 14 | 14 | 13 | 13 |
Median (min–max) correct digits over the inputs, capped at 40; "rev" counts inputs that reverted at that N and are excluded.
The inputs and the ops
| input | parameters | why |
|---|---|---|
| reference | x0 = 1.5 | 1.5 is representable in every format, so a perfect library returns it exactly |
| hundredth | x0 = 0.01 | ln is large and negative |
| tenth | x0 = 0.1 | a typical price ratio |
| near-one-below | x0 = 0.7 | ln is small: cancellation territory |
| just-above-one | x0 = 1.0001 | ln is tiny: the log1p regime |
| two | x0 = 2 | the simplest non-trivial value |
| ten | x0 = 10 | a round decade |
| thousand | x0 = 1000 | three decades |
| million | x0 = 1000000 | six decades, near ABDK's comfortable range |
| awkward | x0 = 123456.789 | a value with no special structure |
Library calls per step: FP127 ln, exp; FP127Lib ln, exp; ABDK ln, exp; Solady lnWad, expWad; PRBMath ln, exp. Parameters reach each adapter floored into its representation (ladder-inputs.json).
The reference input in full: x0 = 1.5
Each cell: the value with the digits that agree with the truth in ink and the rest in red; below it, correct digits against the exact truth, against the format-rounded truth, the signed error in units of the last place, and gas per step.
| N | truth | FP127 (deployed, staticcall) | FP127Lib (inline) | ABDKMath64x64 | Solady FixedPointMathLib | PRBMath SD59x18 |
|---|---|---|---|---|---|---|
| 1 | 1.5 | 1.49999999999999999999999999999999999999706 |
1.49999999999999999999999999999999999999706 |
1.49999999999999999989157978275144955659925 |
1.5 |
1.499999999999999982 |
| 2 | 1.5 | 1.49999999999999999999999999999999999999706 |
1.49999999999999999999999999999999999999706 |
1.49999999999999999978315956550289911319851 |
1.5 |
1.499999999999999966 |
| 5 | 1.5 | 1.49999999999999999999999999999999999999706 |
1.49999999999999999999999999999999999999706 |
1.49999999999999999934947869650869733959553 |
1.5 |
1.499999999999999919 |
| 10 | 1.5 | 1.49999999999999999999999999999999999999706 |
1.49999999999999999999999999999999999999706 |
1.49999999999999999864474728439311945749068 |
1.5 |
1.499999999999999834 |
| 20 | 1.5 | 1.49999999999999999999999999999999999999706 |
1.49999999999999999999999999999999999999706 |
1.49999999999999999718107435153768847158062 |
1.5 |
1.499999999999999678 |
| 50 | 1.5 | 1.49999999999999999999999999999999999999706 |
1.49999999999999999999999999999999999999706 |
1.49999999999999999279005555297139551385044 |
1.5 |
1.499999999999999206 |
| 100 | 1.5 | 1.49999999999999999999999999999999999999706 |
1.49999999999999999999999999999999999999706 |
1.49999999999999998552590099731851580600051 |
1.5 |
1.499999999999998394 |
| 365 | 1.5 | 1.49999999999999999999999999999999999999706 |
1.49999999999999999999999999999999999999706 |
1.49999999999999994681988343958600751193444 |
1.5 |
1.499999999999994003 |
| 1000 | 1.5 | 1.49999999999999999999999999999999999999706 |
1.49999999999999999999999999999999999999706 |
1.4999999999999998541748078006996536259976 |
1.5 |
1.49999999999998402 |
| 10000 | 1.5 | 1.49999999999999999999999999999999999999706 |
1.49999999999999999999999999999999999999706 |
1.49999999999999854104334659488095837787114 |
1.5 |
1.499999999999839112 |
Amortising loan
Step: b = b * (1 + r) - payment. Result: outstanding balance after N daily payments.
Subtracting nearly equal numbers. The payment retires the loan at step 366, so at N = 365 the balance is one payment and relative error is amplified several hundred times.
Over all 8 inputs
| N | FP127 | FP127Lib | ABDK | Solady | PRBMath | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 39 | 40 | 39 | 40 | 20 | 40 | 19 | 40 | 19 | 40 |
| 2 | 38 | 40 | 38 | 40 | 19 | 24 | 19 | 23 | 19 | 23 |
| 5 | 38 | 40 | 38 | 40 | 19 | 24 | 19 | 23 | 19 | 23 |
| 10 | 38 | 40 | 38 | 40 | 19 | 24 | 18 | 22 | 18 | 22 |
| 20 | 37 | 40 | 37 | 40 | 18 | 23 | 18 | 22 | 18 | 22 |
| 50 | 37 | 40 | 37 | 40 | 18 | 23 | 18 | 22 | 18 | 22 |
| 100 | 37 | 40 | 37 | 40 | 17 | 22 | 17 | 21 | 17 | 21 |
| 365 | 34 | 39 | 34 | 39 | 15 | 19 | 14.5 | 18 | 14.5 | 18 |
| 1000 | 36 | 40 | 36 | 40 | 17 | 21.5 | 16.5 | 20.5 | 16.5 | 20.5 |
| 10000 | 35 | 40 | 35 | 40 | 15.5 | 21.5 | 15.5 | 21 | 15.5 | 21 |
Median (min–max) correct digits over the inputs, capped at 40; "rev" counts inputs that reverted at that N and are excluded.
The inputs and the ops
| input | parameters | why |
|---|---|---|
| reference | principal = 300000, rate = 0.05/365, term = 366; payment = principal * rate / (1 - (1 + rate)^(-term)) | a mortgage-sized loan retiring at step 366 |
| small | principal = 10000, rate = 0.05/365, term = 366; payment = principal * rate / (1 - (1 + rate)^(-term)) | a small loan |
| high-rate | principal = 300000, rate = 0.1/365, term = 366; payment = principal * rate / (1 - (1 + rate)^(-term)) | double the rate |
| ten-year | principal = 300000, rate = 0.05/365, term = 3650; payment = principal * rate / (1 - (1 + rate)^(-term)) | a ten-year term: at N = 365 nine tenths remain |
| large-low | principal = 1000000, rate = 0.03/365, term = 366; payment = principal * rate / (1 - (1 + rate)^(-term)) | a large loan at a low rate |
| very-high | principal = 300000, rate = 0.2/365, term = 366; payment = principal * rate / (1 - (1 + rate)^(-term)) | 20% APR |
| micro | principal = 500, rate = 0.05/365, term = 366; payment = principal * rate / (1 - (1 + rate)^(-term)) | a tiny loan: the payment is a few units |
| retires-at-10001 | principal = 300000, rate = 0.05/365, term = 10001; payment = principal * rate / (1 - (1 + rate)^(-term)) | retires one step past the ladder's end, so N = 10,000 is the one-payment cell |
Library calls per step: FP127 mul, sub; FP127Lib mul, sub; ABDK mul, sub; Solady sMulWad, sub; PRBMath mul, sub. Parameters reach each adapter floored into its representation (ladder-inputs.json).
The reference input in full: principal = 300000, rate = 0.05/365, term = 366
Each cell: the value with the digits that agree with the truth in ink and the rest in red; below it, correct digits against the exact truth, against the format-rounded truth, the signed error in units of the last place, and gas per step.
| N | truth | FP127 (deployed, staticcall) | FP127Lib (inline) | ABDKMath64x64 | Solady FixedPointMathLib | PRBMath SD59x18 |
|---|---|---|---|---|---|---|
| 1 | 299200.647990355892260602435720377950399328 | 299200.647990355892260602435720377950399116 |
299200.647990355892260602435720377950399116 |
299200.647990355892257670659354490405590354 |
299200.647990355892256493 |
299200.647990355892256493 |
| 2 | 298401.186480436490807815912870306637504191 | 298401.186480436490807815912870306637503767 |
298401.186480436490807815912870306637503767 |
298401.186480436490801959744604415769586581 |
298401.186480436490799607 |
298401.186480436490799607 |
| 5 | 296002.14479901587277453479645551265335414 | 296002.144799015872774534796455512653353085 |
296002.144799015872774534796455512653353085 |
296002.144799015872759949917492061643997658 |
296002.14479901587275409 |
296002.14479901587275409 |
| 10 | 292001.550590734601252336129721761763542342 | 292001.550590734601252336129721761763540245 |
292001.550590734601252336129721761763540245 |
292001.55059073460122335180776456664553109 |
292001.550590734601211706 |
292001.550590734601211706 |
| 20 | 283992.137644809178562284250368709832406964 | 283992.137644809178562284250368709832402825 |
283992.137644809178562284250368709832402825 |
283992.137644809178505058517780201832181319 |
283992.137644809178482065 |
283992.137644809178482065 |
| 50 | 259897.967206003300994908944979016288932429 | 259897.967206003300994908944979016288922485 |
259897.967206003300994908944979016288922485 |
259897.96720600330085743730115094285437749 |
259897.967206003300802194 |
259897.967206003300802194 |
| 100 | 219520.339088217564302677320754471630738482 | 219520.339088217564302677320754471630719953 |
219520.339088217564302677320754471630719953 |
219520.339088217564046516289567173574326375 |
219520.339088217563943577 |
219520.339088217563943577 |
| 365 | 840.332785974796123490236849916581575798202 | 840.332785974796123490236849916581535234713 |
840.332785974796123490236849916581535234713 |
840.332785974795562720213691620951834693187 |
840.332785974795337317 |
840.332785974795337317 |
| 1000 | -556627.388400841571518712768710676765307471 | -556627.388400841571518712768710676765225396 |
-556627.388400841571518712768710676765225396 |
-556627.388400841570384060383227392554417179 |
-556627.388400841569927932 |
-556627.388400841569927932 |
| 10000 | -16823263.3532103472394141655896251577011087 | -16823263.3532103472394141655896251576317416 |
-16823263.3532103472394141655896251576317416 |
-16823263.3532103462804450766778299741766034 |
-16823263.353210345895187359 |
-16823263.353210345895187359 |
Running geometric mean
Step: L += ln(x_i); g = exp(L / N), x_i = (i + 2) / (i + 1). Result: geometric mean of N terms; truth telescopes to ((N + 2) / 2)^(1 / N).
Index and basket maths: a sum of logs, one division, one exp. The division by N and the final exp expose every accumulated ULP.
Over all 1 input
| N | FP127 | FP127Lib | ABDK | Solady | PRBMath | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 38 | 38 | 38 | 38 | 19 | 19 | 40 | 40 | 16 | 16 |
| 2 | 38 | 38 | 38 | 38 | 18 | 18 | 17 | 17 | 16 | 16 |
| 5 | 38 | 38 | 38 | 38 | 19 | 19 | 17 | 17 | 16 | 16 |
| 10 | 38 | 38 | 38 | 38 | 18 | 18 | 17 | 17 | 16 | 16 |
| 20 | 38 | 38 | 38 | 38 | 18 | 18 | 17 | 17 | 16 | 16 |
| 50 | 38 | 38 | 38 | 38 | 18 | 18 | 17 | 17 | 16 | 16 |
| 100 | 39 | 39 | 39 | 39 | 18 | 18 | 17 | 17 | 16 | 16 |
| 365 | 38 | 38 | 38 | 38 | 18 | 18 | 17 | 17 | 16 | 16 |
| 1000 | 39 | 39 | 39 | 39 | 18 | 18 | 17 | 17 | 16 | 16 |
| 10000 | 38 | 38 | 38 | 38 | 18 | 18 | 17 | 17 | 16 | 16 |
Median (min–max) correct digits over the inputs, capped at 40; "rev" counts inputs that reverted at that N and are excluded.
The inputs and the ops
| input | parameters | why |
|---|---|---|
| reference | the scenario has no parameters; its inputs are the integers 1..N |
Library calls per step: FP127 div, ln, add, exp; FP127Lib div, ln, add, exp; ABDK div, ln, add, exp; Solady sDivWad, lnWad, add, expWad; PRBMath div, ln, add, exp. Parameters reach each adapter floored into its representation (ladder-inputs.json).
The reference input in full:
Each cell: the value with the digits that agree with the truth in ink and the rest in red; below it, correct digits against the exact truth, against the format-rounded truth, the signed error in units of the last place, and gas per step.
| N | truth | FP127 (deployed, staticcall) | FP127Lib (inline) | ABDKMath64x64 | Solady FixedPointMathLib | PRBMath SD59x18 |
|---|---|---|---|---|---|---|
| 1 | 1.5 | 1.49999999999999999999999999999999999999706 |
1.49999999999999999999999999999999999999706 |
1.49999999999999999989157978275144955659925 |
1.5 |
1.499999999999999982 |
| 2 | 1.41421356237309504880168872420969807856967 | 1.41421356237309504880168872420969807856606 |
1.41421356237309504880168872420969807856606 |
1.41421356237309504865536785578328249357583 |
1.414213562373095047 |
1.414213562373095034 |
| 5 | 1.28473515712343933867943306541867483181504 | 1.28473515712343933867943306541867483181363 |
1.28473515712343933867943306541867483181363 |
1.28473515712343933856945041305230859052244 |
1.284735157123439337 |
1.284735157123439324 |
| 10 | 1.19623119885131548973381914341377367153755 | 1.19623119885131548973381914341377367153437 |
1.19623119885131548973381914341377367153437 |
1.19623119885131548953026078829786627011345 |
1.196231198851315488 |
1.196231198851315477 |
| 20 | 1.12737820415783302414307801981343475345086 | 1.12737820415783302414307801981343475344916 |
1.12737820415783302414307801981343475344916 |
1.12737820415783302402173635115012473306706 |
1.127378204157833022 |
1.127378204157833012 |
| 50 | 1.06733184424855890455496508133611557432867 | 1.06733184424855890455496508133611557432543 |
1.06733184424855890455496508133611557432543 |
1.06733184424855890443106787301985605154186 |
1.067331844248558903 |
1.067331844248558893 |
| 100 | 1.04010144984871012198554698020468702744746 | 1.04010144984871012198554698020468702744667 |
1.04010144984871012198554698020468702744667 |
1.04010144984871012182421276537347409885115 |
1.04010144984871012 |
1.040101449848710111 |
| 365 | 1.01438248702624022745474729116356250455137 | 1.01438248702624022745474729116356250454769 |
1.01438248702624022745474729116356250454769 |
1.0143824870262402273362115079358147795574 |
1.014382487026240225 |
1.014382487026240217 |
| 1000 | 1.00623596930045890152123699191085464878457 | 1.00623596930045890152123699191085464878384 |
1.00623596930045890152123699191085464878384 |
1.00623596930045890141761782965446059279202 |
1.006235969300458899 |
1.006235969300458891 |
| 10000 | 1.00085210215007978718759617264671502942782 | 1.00085210215007978718759617264671502942658 |
1.00085210215007978718759617264671502942658 |
1.00085210215007978706630228926677261824807 |
1.000852102150079785 |
1.000852102150079776 |
Black-Scholes d1 along a price path
Step: acc += d1(S); S += tick, with d1 = (ln(S / K) + (r + sigma^2 / 2) T) / (sigma sqrt(T)). Result: sum of d1 over N ticks.
The options-desk case: ln, div, sqrt and mul in one expression, re-evaluated as the spot moves and aggregated.
Over all 8 inputs
| N | FP127 | FP127Lib | ABDK | Solady | PRBMath | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 37 | 37 | 37 | 37 | 18 | 18 | 17 | 17 | 17 | 17 |
| 2 | 37 | 37 | 37 | 37 | 17.5 | 18 | 17.5 | 17.5 | 16 | 16 |
| 5 | 37 | 37 | 37 | 37 | 17 | 18 | 17 | 17 | 15.5 | 15.5 |
| 10 | 37 | 37 | 37 | 37 | 17 | 18 | 17 | 17 | 15.5 | 15.5 |
| 20 | 37 | 37 | 37 | 37 | 17.5 | 18 | 17 | 17 | 16 | 16 |
| 50 | 37 | 37 | 37 | 37 | 17.5 | 18 | 17 | 17 | 16 | 16 |
| 100 | 37 | 37.5 | 37 | 37.5 | 17.5 | 18 | 17 | 17 | 16 | 16 |
| 365 | 37 | 37 | 37 | 37 | 17.5 | 18 | 17 | 17 | 16 | 16 |
| 1000 | 37 | 37.5 | 37 | 37.5 | 17 | 18 | 17 | 17 | 16 | 16 |
| 10000 | 37 | 38 | 37 | 38 | 18 | 18 | 17 | 17 | 16 | 16 |
Median (min–max) correct digits over the inputs, capped at 40; "rev" counts inputs that reverted at that N and are excluded.
The inputs and the ops
| input | parameters | why |
|---|---|---|
| reference | T = 0.5, r = 0.05, sigma = 0.2, spot = 100, strike = 100, tick = 0.01 | at the money, 20% vol, six months |
| low-vol | T = 0.5, r = 0.05, sigma = 0.05, spot = 100, strike = 100, tick = 0.01 | 5% vol: the denominator is small |
| high-vol | T = 0.5, r = 0.05, sigma = 0.8, spot = 100, strike = 100, tick = 0.01 | 80% vol |
| in-the-money | T = 0.5, r = 0.05, sigma = 0.2, spot = 120, strike = 100, tick = 0.01 | ln(S/K) is positive and not small |
| out-of-the-money | T = 0.5, r = 0.05, sigma = 0.2, spot = 80, strike = 100, tick = 0.01 | ln(S/K) is negative |
| short-dated | T = 0.01, r = 0.05, sigma = 0.2, spot = 100, strike = 100, tick = 0.01 | sqrt(T) is small |
| long-dated | T = 2, r = 0.05, sigma = 0.2, spot = 100, strike = 100, tick = 0.01 | two years |
| coarse-ticks | T = 0.5, r = 0.05, sigma = 0.2, spot = 100, strike = 100, tick = 1 | whole-unit ticks: S doubles by N = 100 and reaches 10,100 |
Library calls per step: FP127 div, ln, add, sqrt, mul; FP127Lib div, ln, add, sqrt, mul; ABDK div, ln, add, sqrt, mul; Solady sDivWad, lnWad, add, sqrtWad, sMulWad; PRBMath div, ln, add, sqrt, mul. Parameters reach each adapter floored into its representation (ladder-inputs.json).
The reference input in full: T = 0.5, r = 0.05, sigma = 0.2, spot = 100, strike = 100, tick = 0.01
Each cell: the value with the digits that agree with the truth in ink and the rest in red; below it, correct digits against the exact truth, against the format-rounded truth, the signed error in units of the last place, and gas per step.
| N | truth | FP127 (deployed, staticcall) | FP127Lib (inline) | ABDKMath64x64 | Solady FixedPointMathLib | PRBMath SD59x18 |
|---|---|---|---|---|---|---|
| 1 | 0.247487373415291633540295526736697163749693 | 0.247487373415291633540295526736697163730619 |
0.247487373415291633540295526736697163730619 |
0.247487373415291633360190565182890054529707 |
0.247487373415291635 |
0.247487373415291635 |
| 2 | 0.495681818258787601119016496784504841607013 | 0.49568181825878760111901649678450484156673 |
0.49568181825878760111901649678450484156673 |
0.495681818258787600290932867652671234282025 |
0.495681818258787601 |
0.495681818258787559 |
| 5 | 1.24450687446379156294859558697855008088958 | 1.24450687446379156294859558697855008077686 |
1.24450687446379156294859558697855008077686 |
1.24450687446379155986792702792698150915385 |
1.244506874463791555 |
1.244506874463791342 |
| 10 | 2.50668346780494102921027404289032901502747 | 2.50668346780494102921027404289032901475369 |
2.50668346780494102921027404289032901475369 |
2.50668346780494102210437926125941032751143 |
2.50668346780494101 |
2.506683467804940505 |
| 20 | 5.08401051403297891352661479689167511150537 | 5.08401051403297891352661479689167511088225 |
5.08401051403297891352661479689167511088225 |
5.08401051403297889923552088653480041102739 |
5.084010514032978876 |
5.084010514032977814 |
| 50 | 13.2391487646747260018911032773984733598061 | 13.2391487646747260018911032773984733581989 |
13.2391487646747260018911032773984733581989 |
13.23914876467472596450114172283996083479 |
13.239148764674725887 |
13.239148764674722973 |
| 100 | 28.237364393266085066216191925904648830649 | 28.2373643932660850662161919259046488271773 |
28.2373643932660850662161919259046488271773 |
28.2373643932660849925468139753892415910741 |
28.23736439326608483 |
28.237364393266079006 |
| 365 | 136.745450883799826897439024462329942560739 | 136.745450883799826897439024462329942542832 |
136.745450883799826897439024462329942542832 |
136.745450883799826610829741130315184705069 |
136.745450883799826231 |
136.745450883799804954 |
| 1000 | 589.474773952864477005737983804430862752872 | 589.474773952864477005737983804430862672337 |
589.474773952864477005737983804430862672337 |
589.474773952864476086858664533041363142729 |
589.474773952864476583 |
589.474773952864417545 |
| 10000 | 29787.5592875314291664765495822016511063025 | 29787.5592875314291664765495822016511027086 |
29787.5592875314291664765495822016511027086 |
29787.5592875314291460913610626315417562182 |
29787.559287531429310994 |
29787.559287531428723829 |
Cumulative product of small factors
Step: p = p * (1 + eps_i), eps_i = +eps for odd i, -eps for even i. Result: product after N factors.
The general form of fee accrual, index levels and LP share accounting: many factors a basis point from one. The drift from 1 is where the digits are, and it is small.
Over all 5 inputs
| N | FP127 | FP127Lib | ABDK | Solady | PRBMath | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 38 | 40 | 38 | 40 | 19 | 40 | 40 | 40 | 40 | 40 |
| 2 | 38 | 38 | 38 | 38 | 19 | 19 | 40 | 40 | 40 | 40 |
| 5 | 38 | 38 | 38 | 38 | 18 | 18 | 40 | 40 | 40 | 40 |
| 10 | 37 | 37 | 37 | 37 | 18 | 18 | 18 | 18 | 18 | 18 |
| 20 | 37 | 37 | 37 | 37 | 18 | 18 | 17 | 17 | 17 | 17 |
| 50 | 37 | 37 | 37 | 37 | 17 | 17 | 16 | 16 | 16 | 16 |
| 100 | 36 | 36 | 36 | 36 | 17 | 17 | 16 | 16 | 16 | 16 |
| 365 | 36 | 36 | 36 | 36 | 16 | 16 | 15 | 15 | 15 | 15 |
| 1000 | 35 | 35 | 35 | 35 | 16 | 16 | 15 | 15 | 15 | 15 |
| 10000 | 34 | 34 | 34 | 34 | 15 | 15 | 14 | 14 | 14 | 14 |
Median (min–max) correct digits over the inputs, capped at 40; "rev" counts inputs that reverted at that N and are excluded.
The inputs and the ops
| input | parameters | why |
|---|---|---|
| reference | eps = 0.0001 | a basis point |
| percent | eps = 0.01 | one percent |
| tenth-percent | eps = 0.001 | ten basis points |
| micro | eps = 0.000001 | a hundredth of a basis point: the factors are within WAD's last digits of one |
| five-percent | eps = 0.05 | large factors: the product falls to 4e-6 by N = 10,000 |
Library calls per step: FP127 mul; FP127Lib mul; ABDK mul; Solady sMulWad; PRBMath mul. Parameters reach each adapter floored into its representation (ladder-inputs.json).
The reference input in full: eps = 0.0001
Each cell: the value with the digits that agree with the truth in ink and the rest in red; below it, correct digits against the exact truth, against the format-rounded truth, the signed error in units of the last place, and gas per step.
| N | truth | FP127 (deployed, staticcall) | FP127Lib (inline) | ABDKMath64x64 | Solady FixedPointMathLib | PRBMath SD59x18 |
|---|---|---|---|---|---|---|
| 1 | 1.0001 | 1.00009999999999999999999999999999999999957 |
1.00009999999999999999999999999999999999957 |
1.00009999999999999999123964644631712417322 |
1.0001 |
1.0001 |
| 2 | 0.99999999 | 0.999999989999999999999999999999999999999066 |
0.999999989999999999999999999999999999999066 |
0.999999989999999999950967832784698430259596 |
0.99999999 |
0.99999999 |
| 5 | 1.00009997999800010001 | 1.00009997999800010000999999999999999999409 |
1.00009997999800010000999999999999999999409 |
1.00009997999800009986460722077872276258859 |
1.0000999799980001 |
1.0000999799980001 |
| 10 | 0.9999999500000009999999900000000499999999 | 0.999999950000000999999990000000049999988515 |
0.999999950000000999999990000000049999988515 |
0.999999950000000999714502847304231636371696 |
0.999999950000000997 |
0.999999950000000997 |
| 20 | 0.9999999000000044999998800000020999999748 | 0.9999999000000044999998800000020999999476 |
0.9999999000000044999998800000020999999476 |
0.999999900000004499382375011684587207128061 |
0.999999900000004492 |
0.999999900000004492 |
| 50 | 0.999999750000029999997700000126499994687 | 0.99999975000002999999770000012649999461417 |
0.99999975000002999999770000012649999461417 |
0.9999997500000299984314680590280488559074 |
0.999999750000029977 |
0.999999750000029977 |
| 100 | 0.999999500000122499980400002302999788124016 | 0.999999500000122499980400002302999787978012 |
0.999999500000122499980400002302999787978012 |
0.999999500000122497052421760566076613940822 |
0.999999500000122452 |
0.999999500000122452 |
| 365 | 1.00009817981964726372164161629041717960188 | 1.00009817981964726372164161629041717909031 |
1.00009817981964726372164161629041717909031 |
1.00009817981964725354870546225605210111098 |
1.000098179819647083 |
1.000098179819647083 |
| 1000 | 0.999995000012474979291525730285725552297672 | 0.999995000012474979291525730285725550870416 |
0.999995000012474979291525730285725550870416 |
0.999995000012474951939407674661453029330005 |
0.999995000012474475 |
0.999995000012474475 |
| 10000 | 0.999950001249729179425101682297158079008892 | 0.999950001249729179425101682297158064279421 |
0.999950001249729179425101682297158064279421 |
0.999950001249728906329693883803244602859195 |
0.999950001249724158 |
0.999950001249724158 |
Annual compounding at 10% (README claim check)
Step: b = b * 1.1. Result: balance after N years.
The old README asserted $25,937.42 true against $25,932.38 for Solady at N = 10 with no source. This row regenerates that number.
Over all 5 inputs
| N | FP127 | FP127Lib | ABDK | Solady | PRBMath | |||||
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 38 | 40 | 38 | 40 | 19 | 40 | 40 | 40 | 40 | 40 |
| 2 | 38 | 40 | 38 | 40 | 19 | 39 | 40 | 40 | 40 | 40 |
| 5 | 38 | 40 | 38 | 40 | 18 | 23 | 40 | 40 | 40 | 40 |
| 10 | 37 | 40 | 37 | 40 | 18 | 23 | 40 | 40 | 40 | 40 |
| 20 | 37 | 40 | 37 | 40 | 18 | 22 | 40 | 40 | 40 | 40 |
| 50 | 37 | 40 | 37 | 40 | 17 | 22 | 22 | 22 | 22 | 22 |
| 100 | 36 | 40 | 36 | 40 | 17 | 22 | 22 | 22 | 22 | 22 |
| 365 | 36 | 40 | 36 | 40 | 16 | 20 | 21.5 | 21.5 | 21.5 | 21.5 |
| 1000 | 35 | 40 | 35 | 40 | — | — | 21 | 21 | 21.5 | 21.5 |
| 10000 | — | — | — | — | — | — | — | — | — | — |
Median (min–max) correct digits over the inputs, capped at 40; "rev" counts inputs that reverted at that N and are excluded.
The inputs and the ops
| input | parameters | why |
|---|---|---|
| reference | principal = 10000, rate = 0.1 | the README claim |
| five-pct | principal = 10000, rate = 0.05 | 5% a year |
| unit | principal = 1, rate = 0.1 | one unit |
| million | principal = 1000000, rate = 0.1 | a million units: ABDK overflows sooner |
| fifty-pct | principal = 10000, rate = 0.5 | 50% a year: every library overflows before N = 100 |
Library calls per step: FP127 mul; FP127Lib mul; ABDK mul; Solady sMulWad; PRBMath mul. Parameters reach each adapter floored into its representation (ladder-inputs.json).
The reference input in full: principal = 10000, rate = 0.1
Each cell: the value with the digits that agree with the truth in ink and the rest in red; below it, correct digits against the exact truth, against the format-rounded truth, the signed error in units of the last place, and gas per step.
| N | truth | FP127 (deployed, staticcall) | FP127Lib (inline) | ABDKMath64x64 | Solady FixedPointMathLib | PRBMath SD59x18 |
|---|---|---|---|---|---|---|
| 1 | 11000.0 | 10999.9999999999999999999999999999999999824 |
10999.9999999999999999999999999999999999824 |
10999.9999999999999996747393482543486697978 |
11000.0 |
11000.0 |
| 2 | 12100.0 | 12099.9999999999999999999999999999999999612 |
12099.9999999999999999999999999999999999612 |
12099.9999999999999992844265661595670735551 |
12100.0 |
12100.0 |
| 5 | 16105.1 | 16105.0999999999999999999999999999999998709 |
16105.0999999999999999999999999999999998709 |
16105.0999999999999976188968728307848721215 |
16105.1 |
16105.1 |
| 10 | 25937.424601 | 25937.4246009999999999999999999999999995842 |
25937.4246009999999999999999999999999995842 |
25937.4246009999999923303156020015780569565 |
25937.424601 |
25937.424601 |
| 20 | 67274.9994932560009201 | 67274.9994932560009200999999999999999978432 |
67274.9994932560009200999999999999999978432 |
67274.9994932560008803138352877215577763081 |
67274.9994932560009201 |
67274.9994932560009201 |
| 50 | 1173908.52879695316506666495990358319938982 | 1173908.52879695316506666495990358319929573 |
1173908.52879695316506666495990358319929573 |
1173908.52879695316333107199969348899415422 |
1173908.528796953165066617 |
1173908.528796953165066617 |
| 100 | 137806123.398222701841183371720896367762643 | 137806123.398222701841183371720896367740554 |
137806123.398222701841183371720896367740554 |
137806123.398222701433700108702637421309589 |
137806123.398222701841177177 |
137806123.398222701841177177 |
| 365 | 12833055803133526968.9944800789796565545148 | 12833055803133526968.9944800789796565470065 |
12833055803133526968.9944800789796565470065 |
reverts
|
12833055803133526968.993902795476311067 |
12833055803133526968.993902795476311067 |
| 1000 | 2.46993291800582633412408838508522147770973e+45 | reverts
|
reverts
|
reverts
|
reverts
|
2.46993291800582633412397727736857096657984e+45 |
| 10000 | 8.44990025120034795728149043293472294488798e+417 | reverts
|
reverts
|
reverts
|
reverts
|
reverts
|
Verify calls run(scenario, form, n, p) on 0x798C37A3E5B421D480AC850258466b5598A1A555 through the public Sepolia RPC with the input's floored parameters and compares the raw word with the committed cell. liveMaxN is the largest N on the ladder that the public Sepolia RPC's eth_call completed for every input of that form. Above it the runner reports a bare revert because the adapter ran out of gas under the RPC's eth_call limits (calls needing more than about 40M gas, or a few seconds of execution, fail); the demo page greys out verify above it. Anyone with their own node can run every cell. The whole dataset is ladder.json; the generator is make ladder.