From d2a4aca790aeef5b56324a8a9431b9e2da059761 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Tue, 12 May 2026 16:53:05 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Golf=20`cbrt`=20by=20u?= =?UTF-8?q?sing=20a=20small=20table=20for=20an=20even=20better=20initial?= =?UTF-8?q?=20estimate=20and=20removing=20another=20iteration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/clz/FixedPointMathLib.sol | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/utils/clz/FixedPointMathLib.sol b/src/utils/clz/FixedPointMathLib.sol index c349e0b59..1d4ba89bb 100644 --- a/src/utils/clz/FixedPointMathLib.sol +++ b/src/utils/clz/FixedPointMathLib.sol @@ -804,16 +804,16 @@ library FixedPointMathLib { function cbrt(uint256 x) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { - // Initial guess z โ‰ˆ โˆ›(3/4) ยท 2๐žฅ where q = โŒŠ(257 โˆ’ clz(x)) / 3โŒ‹. The - // multiplier 233/256 โ‰ˆ 0.909 โ‰ˆ โˆ›(3/4) balances the worst-case - // over/underestimate across each octave triplet (ฮต_over โ‰ˆ 0.445, - // ฮต_under โ‰ˆ โˆ’0.278), giving >85 bits of precision after 6 N-R - // iterations. The `add(..., 1)` term ensures z โ‰ฅ 1 when x > 0 (the - // `shr` can produce 0 for small `q`) - z := add(shr(8, shl(div(sub(257, clz(x)), 3), 233)), 1) - - // 6 Newton-Raphson iterations. - z := div(add(add(div(x, mul(z, z)), z), z), 3) + // Initial guess z โ‰ˆ c ยท 2๐žฅ where b = โŒŠlogโ‚‚(x)โŒ‹, q = โŒŠb / 3โŒ‹. The + // 8-bit fixed-point multipliers `c`: 144/128, 181/128, and 229/128 + // are selected by `b mod 3` to balance each octave's worst-case + // final error. This gives >98 bits of precision after only 5 + // Newton-Raphson iterations. The `or(1, ...)` keeps z โ‰ฅ 1 when the + // shifted estimate is 0. + let b := sub(255, clz(x)) + z := or(shr(7, shl(div(b, 3), byte(add(mod(b, 3), 29), 0x90b5e5))), 1) + + // 5 Newton-Raphson iterations z := div(add(add(div(x, mul(z, z)), z), z), 3) z := div(add(add(div(x, mul(z, z)), z), z), 3) z := div(add(add(div(x, mul(z, z)), z), z), 3) From 6b69bf36cb16400068476dce9f0709aebcedcc77 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Tue, 12 May 2026 17:03:48 +0200 Subject: [PATCH 2/2] Formatting --- src/utils/clz/FixedPointMathLib.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/clz/FixedPointMathLib.sol b/src/utils/clz/FixedPointMathLib.sol index 1d4ba89bb..c3be70416 100644 --- a/src/utils/clz/FixedPointMathLib.sol +++ b/src/utils/clz/FixedPointMathLib.sol @@ -808,7 +808,7 @@ library FixedPointMathLib { // 8-bit fixed-point multipliers `c`: 144/128, 181/128, and 229/128 // are selected by `b mod 3` to balance each octave's worst-case // final error. This gives >98 bits of precision after only 5 - // Newton-Raphson iterations. The `or(1, ...)` keeps z โ‰ฅ 1 when the + // Newton-Raphson iterations. The `or(..., 1)` keeps z โ‰ฅ 1 when the // shifted estimate is 0. let b := sub(255, clz(x)) z := or(shr(7, shl(div(b, 3), byte(add(mod(b, 3), 29), 0x90b5e5))), 1)