I have been working for a few days on writing get, set, and clear bitwise functions in JavaScript to clear not individual bits from an integer n, but to clear entire ranges of bits in n.
For example, using the functions below, I would expect this behavior:
getNumBits(0b101) // 3
getNumBits(0b10100000) // 8
// getBitRange(integer, startIndex, size)
getBitRange(0b101110010001111, 1, 4) // 1110
getBitRange(0b101110010001111, 5, 7) // 1
// setBitRange(integer, startIndex, value)
setBitRange(0b101110010001111, 5, 0b1001) // 0b101111001001111
// clearBitRange(integer, startIndex, size)
clearBitRange(0b101110010001111, 5, 5) // 0b101110000001111
clearBitRange(0b101110010001111, 2, 3) // 0b100000000001111
How can I optimize these functions by removing or reordering any of the operations? Can we cut out any steps? I did my best to figure out how to just barely implement the function, but I am no master at bit operations yet. Wondering if one could rewrite these 4 functions to make them more optimal. Please keep each instruction on its own line so it's easier to see :)
function getNumBits(n) {
let i = 0
while (n) {
i++
n >>= 1
}
return i
}
function getBitRange(n, l, s) {
let r = 8 - l - s
let p = 1 << p
let o = p - 1
let ol = o << r
let or = o >> l
let om = or & ol
let x = n & om
return x >> r
}
function setBitRange(n, i, x) {
let o = 0xff // 0b11111111
let c = getNumBits(x)
let j = 8 - i // right side start
let k = j - c // right side remaining
let h = c + i
let a = x << k // set bits
let b = a ^ o // set bits flip
let d = o >> h // mask right
let q = d ^ b //
let m = o >> j // mask left
let s = m << j
let t = s ^ q // clear bits!
let w = n | a // set the set bits
let z = w & ~t // perform some magic https://stackoverflow.com/q/8965521/169992
return z
}
function clearBitRange(n, i, c) {
let s = i + c
let r = 8 - s
let p = 1 << 8
let o = p - 1
let j = o >> i
let k = o << r
let h = j & k
let g = ~h
let z = n & g
return z
}
This is only concerned with 8-bit numbers.