From 8746667ed2a5de37aa289e72f0d3444559be5c51 Mon Sep 17 00:00:00 2001 From: Chris Gorman Date: Thu, 29 Jun 2023 16:05:42 -0700 Subject: [PATCH 1/4] Improved integer square root. --- contracts/libraries/Math.sol | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/contracts/libraries/Math.sol b/contracts/libraries/Math.sol index 1cab10d26..784c71f75 100644 --- a/contracts/libraries/Math.sol +++ b/contracts/libraries/Math.sol @@ -7,17 +7,26 @@ library Math { z = x < y ? x : y; } - // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) - function sqrt(uint y) internal pure returns (uint z) { - if (y > 3) { - z = y; - uint x = y / 2 + 1; - while (x < z) { - z = x; - x = (y / x + x) / 2; - } - } else if (y != 0) { - z = 1; - } +function sqrt(uint256 x) internal pure returns (uint256 result) { + unchecked { + if (x <= 1) { return x; } + if (x >= ((1 << 128) - 1)**2) { return (1 << 128) - 1; } + uint256 xAux = x; + result = 1; + if (xAux >= (1 << 128)) { xAux >>= 128; result <<= 64; } + if (xAux >= (1 << 64 )) { xAux >>= 64; result <<= 32; } + if (xAux >= (1 << 32 )) { xAux >>= 32; result <<= 16; } + if (xAux >= (1 << 16 )) { xAux >>= 16; result <<= 8; } + if (xAux >= (1 << 8 )) { xAux >>= 8; result <<= 4; } + if (xAux >= (1 << 4 )) { xAux >>= 4; result <<= 2; } + if (xAux >= (1 << 2 )) { result <<= 1; } + result += (result >> 1); + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + return result * result <= x ? result : (result - 1); } } From fac56e7267e6c151604690208e2e6dfe030cdeee Mon Sep 17 00:00:00 2001 From: Chris Gorman Date: Sat, 22 Jul 2023 14:14:59 -0700 Subject: [PATCH 2/4] Small updates to sqrt. --- contracts/libraries/Math.sol | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/contracts/libraries/Math.sol b/contracts/libraries/Math.sol index 784c71f75..cc2e10a62 100644 --- a/contracts/libraries/Math.sol +++ b/contracts/libraries/Math.sol @@ -7,12 +7,12 @@ library Math { z = x < y ? x : y; } -function sqrt(uint256 x) internal pure returns (uint256 result) { +function sqrt(uint256 x) internal pure returns (uint256) { unchecked { if (x <= 1) { return x; } if (x >= ((1 << 128) - 1)**2) { return (1 << 128) - 1; } uint256 xAux = x; - result = 1; + uint256 result = 1; if (xAux >= (1 << 128)) { xAux >>= 128; result <<= 64; } if (xAux >= (1 << 64 )) { xAux >>= 64; result <<= 32; } if (xAux >= (1 << 32 )) { xAux >>= 32; result <<= 16; } @@ -27,6 +27,9 @@ function sqrt(uint256 x) internal pure returns (uint256 result) { result = (result + x / result) >> 1; result = (result + x / result) >> 1; result = (result + x / result) >> 1; - return result * result <= x ? result : (result - 1); + if (result * result <= x) { + return result; + } + return result-1; } } From c7ae038ed39c1cd168dd183f5f412d3140c7a000 Mon Sep 17 00:00:00 2001 From: Chris Gorman Date: Mon, 24 Jul 2023 09:46:55 -0700 Subject: [PATCH 3/4] Fixed variable naming. --- contracts/libraries/Math.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/libraries/Math.sol b/contracts/libraries/Math.sol index cc2e10a62..16ec34b5e 100644 --- a/contracts/libraries/Math.sol +++ b/contracts/libraries/Math.sol @@ -27,7 +27,7 @@ function sqrt(uint256 x) internal pure returns (uint256) { result = (result + x / result) >> 1; result = (result + x / result) >> 1; result = (result + x / result) >> 1; - if (result * result <= x) { + if (result * result <= a) { return result; } return result-1; From 7e695379647b728c9268c14030f1a89af077cd34 Mon Sep 17 00:00:00 2001 From: Chris Gorman Date: Thu, 31 Aug 2023 18:48:05 -0700 Subject: [PATCH 4/4] Minor improvement. --- contracts/libraries/Math.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/libraries/Math.sol b/contracts/libraries/Math.sol index 16ec34b5e..a4ae4c3f4 100644 --- a/contracts/libraries/Math.sol +++ b/contracts/libraries/Math.sol @@ -13,14 +13,14 @@ function sqrt(uint256 x) internal pure returns (uint256) { if (x >= ((1 << 128) - 1)**2) { return (1 << 128) - 1; } uint256 xAux = x; uint256 result = 1; - if (xAux >= (1 << 128)) { xAux >>= 128; result <<= 64; } + if (xAux >= (1 << 128)) { xAux >>= 128; result = 1 << 64; } if (xAux >= (1 << 64 )) { xAux >>= 64; result <<= 32; } if (xAux >= (1 << 32 )) { xAux >>= 32; result <<= 16; } if (xAux >= (1 << 16 )) { xAux >>= 16; result <<= 8; } if (xAux >= (1 << 8 )) { xAux >>= 8; result <<= 4; } if (xAux >= (1 << 4 )) { xAux >>= 4; result <<= 2; } if (xAux >= (1 << 2 )) { result <<= 1; } - result += (result >> 1); + result = (3 * result) >> 1; result = (result + x / result) >> 1; result = (result + x / result) >> 1; result = (result + x / result) >> 1;