@@ -1472,7 +1472,7 @@ library Lib512MathArithmetic {
14721472 // `Y` _ultimately_ approximates the inverse square root of fixnum `M` as a
14731473 // Q3.253. However, as a gas optimization, the number of fractional bits in `Y` rises
14741474 // through the steps, giving an inhomogeneous fixed-point representation. Y ≈∈ [√½, √2]
1475- uint256 Y; // scale: 2⁽²⁵⁵ ⁺ᵉ⁾
1475+ uint256 Y; // scale: 2⁽²⁵³ ⁺ᵉ⁾
14761476 assembly ("memory-safe" ) {
14771477 // Extract the upper 6 bits of `M` to be used as a table index. `M >> 250 < 16` is
14781478 // invalid (that would imply M<½), so our lookup table only needs to handle only 16
@@ -1535,10 +1535,13 @@ library Lib512MathArithmetic {
15351535 Y = Y * T >> 116 ; // scale: 2¹²⁷
15361536 }
15371537 // `Y` is Q129.127
1538- if (invE < 79 ) { // Empirically, 79 is the correct limit. 78 causes fuzzing errors.
1539- // For small `e` (lower values of `x`), we can skip the 5th N-R iteration. The
1540- // correct bits that this iteration would obtain are shifted away during the
1541- // denormalization step. This branch is net gas-optimizing.
1538+ if (invE < 95 - Mbucket) {
1539+ // Generally speaking, for relatively smaller `e` (lower values of `x`) and for
1540+ // relatively larger `M`, we can skip the 5th N-R iteration. The constant `95` is
1541+ // derived by extensive fuzzing. Attempting a higher-order approximation of the
1542+ // relationship between `M` and `invE` consumes, on average, more gas. The correct
1543+ // bits that this iteration would obtain are shifted away during the denormalization
1544+ // step. This branch is net gas-optimizing.
15421545 uint256 Y2 = Y * Y; // scale: 2²⁵⁴
15431546 uint256 MY2 = _inaccurateMulHi (M, Y2); // scale: 2²⁵⁴
15441547 uint256 T = 1.5 * 2 ** 254 - MY2; // scale: 2²⁵⁴
0 commit comments