var num = 9;
num.toString(2); //returns 1001
(~num).toString(2); // returns "-1010"
~(num - 1).toString(2); //returns "-1001"
As you can see from the example, there are two main problems. The first is that the sign bit is replaced with a negative sign. And second, the bits don’t get toggled.
To fix this problem most programmers would just XOR the number with a mask to toggle the bits. Although this works, it quickly produces the unintended result once you XOR a number larger than the mask.
Example:
var BIT_MASK = 0xF;
(9).toString(2); //returns "1001"
(9 ^ BIT_MASK).toString(2); //returns "110"
(30).toString(2); //returns "11110"
(30 ^ BIT_MASK).toString(2); //returns "10001"
A simple solution to this problem is to not to use javascript for bitwise operations.
However, if javascript is required then use the following code to implement bitwise NOT operation.
Method 1: Simple approach.
var toggleBits = function( dec ){
var mask = 0xFFFFFFF;
return ( dec ^ mask ).toString(2).match( RegExp( "[01]{"+(dec.toString(2).length)+"}$" ) )[0];
};
var num = 23;
num.toString(2); // returns 10111
num = toggleBits(num); // num = 01000;
num = parseInt( num, 2); // num = 8, binary = 1000
Method 2: More advance features.
// Programer: Larry Battle
// Purpose: Provide a bit toggle function for javascript.
var getStrCopy = function (str, copies) {
var newStr = str;
copies = (copies > 0) ? copies : 1;
while (--copies) {
newStr += str;
}
return newStr;
};
var convertDecToBase = function ( dec, base, length, padding ) {
padding = padding || '0' ;
var num = dec.toString( base );
length = length || num.length;
if (num.length !== length) {
if (num.length > length) {
throw new Error("convertDecToBase(): num(" + num + ") > length(" + length + ") too long.");
}
num = getStrCopy( padding, (length - num.length)) + num;
}
return num;
};
var formatBinaryStr = function( str ){
return str.replace( /\d{4}/g, '$& ' ).replace( /\s$/,'');
};
var toggleBits = function( dec, length, doFormat ){
var str = convertDecToBase( dec, 2, length || 8 );
var binaryStr = str.replace( /0/g, 'o' ).replace( /1/g, '0').replace( /o/g, '1' );
return ( doFormat ) ? formatBinaryStr( binaryStr ) : binaryStr ;
};
// The following requires Firebug or Google Chrome Dev Tools
clear();
// Test case
var num = 230;
var testNum = parseInt( toggleBits(num), 2 );
testNum = parseInt( toggleBits( testNum ), 2 );
console.log( "(Test Case) 2 Bit Toggles will give the original number: " + (testNum == num) );
// Examples:
console.log( toggleBits( 1 ) ); // displays "11111110"
console.log( toggleBits( 2 ) ); // displays "11111101"
console.log( toggleBits( 50, 16 ) );// displays "1111111111001101"
console.log( toggleBits( 15, 8, true ) ); // displays "1111 0000"
console.log( toggleBits( 520, 16, true ) ); // displays "1111 1101 1111 0111"
For more information check out Mozilla’s Bitwise Operators Reference
What REALLY is Data Science? Told by a Data Scientist - By Joma Tech
Writing perfect code is a challenging process. That's where code reviews come in to help…
"The Next Leap: How A.I. will change the 3D industry - Andrew Price - Blender"
"Captain Disillusion: World's Greatest Blenderer - Live at the Blender Conference 2018 - CaptainDisillusion"
My 5 Favorite Linux Shell Tricks for SPEEEEEED (and efficiency) - By tutoriaLinux > What's…
View Comments
why not do this instead?
var toggleBits = function( dec ){
return ( dec | 0x80000000 ).toString(2);
};
You're method works too.
But I was going for a way to invert the binary values starting from the left most 1.
Now lets compare the two functions with value for ten.
toggleBits( 10 );
Your method gives 1111111111111111111111111110101
My method gives 0101
sorry, i forgot to put the one-complement:
var toggleBits = function( dec ){
return ( ~(dec | 0x80000000) ).toString(2);
};
this is only necessary for displaying the number in binary using the toString method. The number is stored perfectly fine in memory. It is more a consequence of the toString's implementation.