From 3a104e93806f0e1f237e93530cfd87a0224e45f6 Mon Sep 17 00:00:00 2001 From: cairo Date: Mon, 28 Oct 2024 18:34:26 +0100 Subject: [PATCH] Optimized binary search --- contracts/utils/math/Math.sol | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/contracts/utils/math/Math.sol b/contracts/utils/math/Math.sol index 85a420b1a7b..d671d858739 100644 --- a/contracts/utils/math/Math.sol +++ b/contracts/utils/math/Math.sol @@ -640,29 +640,17 @@ library Math { * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ - function log256(uint256 value) internal pure returns (uint256) { - uint256 result = 0; - uint256 isGt; - unchecked { - isGt = SafeCast.toUint(value > (1 << 128) - 1); - value >>= isGt * 128; - result += isGt * 16; - - isGt = SafeCast.toUint(value > (1 << 64) - 1); - value >>= isGt * 64; - result += isGt * 8; - - isGt = SafeCast.toUint(value > (1 << 32) - 1); - value >>= isGt * 32; - result += isGt * 4; - - isGt = SafeCast.toUint(value > (1 << 16) - 1); - value >>= isGt * 16; - result += isGt * 2; - - result += SafeCast.toUint(value > (1 << 8) - 1); - } - return result; + function log256(uint256 x) internal pure returns (uint256 r) { + // If value has upper 128 bits set, log2 result is at least 128 + r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7; + // If upper 64 bits of 128-bit half set, add 64 to result + r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6; + // If upper 32 bits of 64-bit half set, add 32 to result + r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5; + // If upper 16 bits of 32-bit half set, add 16 to result + r |= SafeCast.toUint((x >> r) > 0xffff) << 4; + // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8 + return (r >> 3) | SafeCast.toUint((x >> r) > 0xff); } /**