Invert Unsigned Arbitrary Binary Bits In Javascript
Solution 1:
You can create a function that flips the required number of digits like so
var flipbits = function (v, digits) {
return ~v & (Math.pow(2, digits) - 1);
}
console.log(flipbits(5, 3)); // outputs 2console.log(flipbits(2, 3)); // outputs 5
note - this isn't "arbitrary number of bits" ... it's 32 at best
working with strings, you can have arbitrary bit length (this one wont work without transpiling in Internet Exploder)
varflipbits = str => str.split('').map(b => (1 - b).toString()).join('');
console.log(flipbits('010')); // outputs 101console.log(flipbits('101')); // outputs 010
The above in ES5
var flipbits = functionflipbits(str) {
return str.split('').map(function (b) {
return (1 - b).toString();
}).join('');
};
console.log(flipbits('010')); // outputs 101console.log(flipbits('101')); // outputs 010
Solution 2:
Inverting the bits will always be the same, but to convert an unsigned integer to a signed integer you can use the unsigned >>>
shift operator to work on unsigned numbers:
console.log(~5); // -6console.log(~5>>>0); // 4294967290
If you want to make sure you only flip the significant bits in the number, you'll instead want to mask it via an &
operation with how many significant bits you need. Here is an example of the significant bit masking:
functioninvert(x) {
let significant = 0;
let test = x;
while (test > 1) {
test = test >> 1;
significant = (significant << 1) | 1;
}
return (~x) & significant;
}
console.log(invert(5)); // 2 (010 in binary)
Solution 3:
In JavaScript, ~ or tilde does this
-(N+1)
So your current operation is correct but not what you are looking for:
~5
-(5 + 1)-6
Solution 4:
You can use String.prototype.replace()
with RegExp
/(0)|(1)/
functiontoggle(n) {
return n.replace(/(0)|(1)/g, function(m, p1, p2) { return p2 ? 0 : 1 });
}
console.log(
toggle("10100"),
toggle("101")
)
Solution 5:
You can use a function that converts numbers to binary as a string, flips the 0s and 1s, then converts back to a number. It seems to give the expected results, but looks pretty ugly:
functionflipBits(n) {
returnparseInt(n.toString(2).split('').map(bit =>1 - bit).join(''),2)
}
[0,1,2,3,4,5,123,987679876,987679875].forEach(
n =>console.log(n + ' -> ' + flipBits(n))
);
Maybe there's a mix of bitwise operators to do the same thing.
Edit
It seems you're working with strings, so just split, flip and join again:
// Requires support for ECMAScript ed 5.1 for map and // ECMAScript 2015 for arrow functionsfunctionflipStringBits(s) {
return s.split('').map(c =>1 - c).join('');
}
['0','010','110','10011100110'].forEach(
v =>console.log(v + ' -> ' + flipStringBits(v))
);
Basic function for ECMAScript ed 3 (works everywhere, even IE 4).
functionflipStringBitsEd3(s) {
var b = s.split('')
for (var i = 0, iLen = b.length; i < iLen; i++) {
b[i] = 1 - b[i];
}
return b.join('');
}
// Testsconsole.log('Ed 3 version');
var data = ['0', '010', '110', '10011100110'];
for (var i = 0, iLen = data.length; i < iLen; i++) {
console.log(data[i] + ' ->\n' + flipStringBitsEd3(data[i]) + '\n');
}
Works with any length string. The ed 3 version will work everywhere and is probably faster than functions using newer features.
Post a Comment for "Invert Unsigned Arbitrary Binary Bits In Javascript"