Skip to content

Commit

Permalink
✨ Add commonPrefix (#1306)
Browse files Browse the repository at this point in the history
  • Loading branch information
JhChoy authored Jan 16, 2025
1 parent 00ce639 commit 51a5a7e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/utils/LibBit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
Expand Down
13 changes: 13 additions & 0 deletions test/LibBit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

0 comments on commit 51a5a7e

Please sign in to comment.