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.