Reputation: 6873
I am storing four number
s, where 20 <= n >= -20
, as 4 x 6-bit two's complements, in one JS primitive number
by doing this:
function convertToBits(a: number, b: number, c: number, d: number) {
const mask = 0b111111;
return ((d & mask) << 18) | ((c & mask) << 12) | ((b & mask) << 6) | (a & mask);
}
convertToBits(-7, 31, 12, -32); // => 0b100000_001100_011111_111001
Given:
let a = convertToBits(-7, 31, 12, -31); // => 0b100001_001100_011111_111001
let b = convertToBits(7, -31, -12, 31); // => 0b011111_110100_100001_000111
I'm looking for an efficient way to add each of the four components of a
with its corresponding component in b
such that, given the inputs above:
function addBits(a: number, b: number) {
// Missing implementation
}
addBits(a, b); // => 0b0;
Upvotes: 0
Views: 45
Reputation: 5040
You can use the fact that for a single bit, the result of '+' (ignoring carry) is given by XOR. You can then calculate first the sum without the sign bits, possibly generating a carry in the sign bits, but not interfering with the next 6-bit group, and then factor in the sum of the sign bits. Untested code:
function addBits(x: number, y: number) {
const signmask = 0b100000_100000_100000_100000;
let sum_without_sign_bits = ((x & ~signmask) + (y & ~signmask));
let sum_of_sign_bits = (x ^ y) & signmask;
return sum_without_sign_bits ^ sum_of_sign_bits;
}
Upvotes: 1
Reputation: 6873
So I've come up with a way to get the result I'm looking for but I can't help but think there might be a more efficient way to do this. Nevertheless, it provides the correct output.
function addBits(a: number, b: number) {
const mask = 0b111111;
const m = ((a & mask) + (b & mask)) & mask;
const n = (((a >> 6) & mask) + ((b >> 6) & mask)) & mask;
const o = (((a >> 12) & mask) + ((b >> 12) & mask)) & mask;
const p = ((a >> 18) & mask) + ((b >> 18) & (mask)) & mask;
return m | (n << 6) | (o << 12) | (p << 18);
}
Upvotes: 0