mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
95 lines
2.7 KiB
Solidity
95 lines
2.7 KiB
Solidity
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
pragma solidity >=0.5.0;
|
|
|
|
/// @title BitMath
|
|
/// @dev This library provides functionality for computing bit properties of an unsigned integer
|
|
library BitMath {
|
|
/// @notice Returns the index of the most significant bit of the number,
|
|
/// where the least significant bit is at index 0 and the most significant bit is at index 255
|
|
/// @dev The function satisfies the property:
|
|
/// x >= 2**mostSignificantBit(x) and x < 2**(mostSignificantBit(x)+1)
|
|
/// @param x the value for which to compute the most significant bit, must be greater than 0
|
|
/// @return r the index of the most significant bit
|
|
function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {
|
|
require(x > 0);
|
|
|
|
if (x >= 0x100000000000000000000000000000000) {
|
|
x >>= 128;
|
|
r += 128;
|
|
}
|
|
if (x >= 0x10000000000000000) {
|
|
x >>= 64;
|
|
r += 64;
|
|
}
|
|
if (x >= 0x100000000) {
|
|
x >>= 32;
|
|
r += 32;
|
|
}
|
|
if (x >= 0x10000) {
|
|
x >>= 16;
|
|
r += 16;
|
|
}
|
|
if (x >= 0x100) {
|
|
x >>= 8;
|
|
r += 8;
|
|
}
|
|
if (x >= 0x10) {
|
|
x >>= 4;
|
|
r += 4;
|
|
}
|
|
if (x >= 0x4) {
|
|
x >>= 2;
|
|
r += 2;
|
|
}
|
|
if (x >= 0x2) r += 1;
|
|
}
|
|
|
|
/// @notice Returns the index of the least significant bit of the number,
|
|
/// where the least significant bit is at index 0 and the most significant bit is at index 255
|
|
/// @dev The function satisfies the property:
|
|
/// (x & 2**leastSignificantBit(x)) != 0 and (x & (2**(leastSignificantBit(x)) - 1)) == 0)
|
|
/// @param x the value for which to compute the least significant bit, must be greater than 0
|
|
/// @return r the index of the least significant bit
|
|
function leastSignificantBit(uint256 x) internal pure returns (uint8 r) {
|
|
require(x > 0);
|
|
|
|
r = 255;
|
|
if (x & type(uint128).max > 0) {
|
|
r -= 128;
|
|
} else {
|
|
x >>= 128;
|
|
}
|
|
if (x & type(uint64).max > 0) {
|
|
r -= 64;
|
|
} else {
|
|
x >>= 64;
|
|
}
|
|
if (x & type(uint32).max > 0) {
|
|
r -= 32;
|
|
} else {
|
|
x >>= 32;
|
|
}
|
|
if (x & type(uint16).max > 0) {
|
|
r -= 16;
|
|
} else {
|
|
x >>= 16;
|
|
}
|
|
if (x & type(uint8).max > 0) {
|
|
r -= 8;
|
|
} else {
|
|
x >>= 8;
|
|
}
|
|
if (x & 0xf > 0) {
|
|
r -= 4;
|
|
} else {
|
|
x >>= 4;
|
|
}
|
|
if (x & 0x3 > 0) {
|
|
r -= 2;
|
|
} else {
|
|
x >>= 2;
|
|
}
|
|
if (x & 0x1 > 0) r -= 1;
|
|
}
|
|
}
|