/*
countTrailingZeros:
-------------------
Returns the number of trailing zeros in a 64‑bit integer (bigint).
Algorithm:
- Isolate lowest set bit: x & -x
- Convert to number and take log2 to get the bit index.
*/
function countTrailingZeros(x: bigint): number {
const lowest: bigint = x & -x; // isolate lowest set bit
const index: number = Math.log2(Number(lowest)); // index (0–63)
return index;
}
/*
findNthSetBit64:
----------------
Given:
- x : a 64-bit integer (bigint)
- n : which set bit to find (1-based index)
Returns:
A 64-bit mask (bigint) with ONLY the Nth set bit of x turned on.
If n is larger than the number of set bits, returns 0n.
Algorithm:
- Use countTrailingZeros(x) to locate the lowest set bit.
- Remove that bit using x &= (x - 1n).
- When we reach the Nth one, return 1n << index.
*/
function findNthSetBit64(x: bigint, n: number): bigint {
let current: bigint = x;
let count: number = n;
while (current !== 0n) {
const index: number = countTrailingZeros(current);
count -= 1;
if (count === 0) {
return 1n << BigInt(index);
}
// Remove the lowest set bit
current &= (current - 1n);
}
return 0n;
}
/*
toBinary64:
-----------
Convert bigint to a padded 64-bit binary string.
*/
function toBinary64(x: bigint): string {
const raw: string = x.toString(2);
return raw.padStart(64, "0");
}
// --------------------
// Main
// --------------------
const value: bigint =
0b0000000000000000000010000000000000001101001101101100100010100000n;
const n: number = 4;
const result: bigint = findNthSetBit64(value, n);
console.log("Input value: ", toBinary64(value));
console.log("N =", n);
console.log("Result mask: ", toBinary64(result));
/*
run:
Input value: 0000000000000000000010000000000000001101001101101100100010100000
N = 4
Result mask: 0000000000000000000000000000000000000000000000000100000000000000
*/