Skip to content

Instantly share code, notes, and snippets.

@EnriqCG
Created January 19, 2023 16:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EnriqCG/29371055d62b567e485159e0ff85d88c to your computer and use it in GitHub Desktop.
Save EnriqCG/29371055d62b567e485159e0ff85d88c to your computer and use it in GitHub Desktop.
Gets the position of the first zero bit (Little-Endian) of a 255 bit number
/**
* Gets the position of the first zero bit (Little-Endian) of a 255 bit number.
*
* 001010111111111
* ^
* By doing an AND operation between the input and it's 2's complement, we get a
* number whose single 1 bit is the first zero byte in the sequence.
*/
const { constants, BigNumber } = require("ethers");
const input = BigNumber.from(72)
// NOT operator = XOR with a bitmask of all ones
const bitMask = constants.MaxUint256
const reverse = input.xor(bitMask)
// EthersJS two's complement is not working here so we are just doing
// it manually. NOT(input) + 1 (https://en.wikipedia.org/wiki/Two%27s_complement)
const twosComplement = reverse.add(BigNumber.from(1))
// Find position of resulting bit by doing a log2
const index = Math.log2(input.and(twosComplement).toNumber())
console.log(index)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment