From 51a5a7ee879ea2ddc7fe69164bd6f008716bbb33 Mon Sep 17 00:00:00 2001 From: JChoy <jchoyeclipse@gmail.com> Date: Fri, 17 Jan 2025 08:17:52 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20commonPrefix=20(#1306)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/LibBit.sol | 11 +++++++++++ test/LibBit.t.sol | 13 +++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/utils/LibBit.sol b/src/utils/LibBit.sol index eb617691a0..b6a8826cd1 100644 --- a/src/utils/LibBit.sol +++ b/src/utils/LibBit.sol @@ -117,6 +117,17 @@ library LibBit { } } + /// @dev Returns the common prefix of `x` and `y` in hex format. + function commonPrefix(uint256 x, uint256 y) internal pure returns (uint256 r) { + uint256 lz = clz(x ^ y); + assembly { + let nibbles := div(lz, 4) + // Since nibbles is always <= 64, there's no risk of underflow. + let bits := mul(sub(64, nibbles), 4) + r := shl(bits, shr(bits, x)) + } + } + /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* BOOLEAN OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ diff --git a/test/LibBit.t.sol b/test/LibBit.t.sol index 2d9694288c..ba641b1b53 100644 --- a/test/LibBit.t.sol +++ b/test/LibBit.t.sol @@ -224,4 +224,17 @@ contract LibBitTest is SoladyTest { r := mload(0x00) } } + + function testCommonPrefix() public { + assertEq(LibBit.commonPrefix(0x1, 0x2), 0); + assertEq(LibBit.commonPrefix(0x1234abc, 0x1234bbb), 0x1234000); + assertEq(LibBit.commonPrefix(0x1234abc, 0x1234abc), 0x1234abc); + } + + function testCommonPrefix(uint256 x, uint8 p) public { + uint256 y = x ^ (1 << p); + uint256 l = 63 - p / 4; + uint256 r = l == 0 ? 0 : x & ~((1 << ((64 - l) * 4)) - 1); + assertEq(LibBit.commonPrefix(x, y), r); + } }