Bitwise NOT (~) (JavaScript)
Learn Bitwise NOT (~) (JavaScript) step by step with clear examples and exercises.
Why This Matters
The Bitwise NOT operator is an essential concept in JavaScript programming as it allows developers to manipulate binary numbers at the bit level. Understanding this operator can help you solve complex problems, optimize code, and stand out in coding interviews.
In modern computing, data is often stored and processed in binary format. The Bitwise NOT operator gives JavaScript programmers the ability to work directly with binary numbers, which can lead to more efficient solutions for various programming tasks. Additionally, understanding bitwise operations is essential for interview preparation as many questions involve manipulating binary data.
Prerequisites
To fully grasp this lesson, you should be familiar with the following concepts:
- JavaScript basics (variables, data types, functions)
- Understanding of numbers in JavaScript (integer, floating-point)
- Basic understanding of binary and hexadecimal number systems
- Familiarity with logical operators (AND, OR, NOT)
- Comprehension of bitwise operators like AND (
&), OR (|), XOR (^), and shift operators (<<,>>) - Knowledge of JavaScript data structures such as arrays and objects
Core Concept
The Bitwise NOT operator (~) is a unary operator that computes the bitwise complement of its operand. It flips all the bits in the binary representation of a number.
Let's take a look at an example:
const a = 5; // binary: 000000000000000000000101
console.log(~a); // output: -7, binary: 111111111111111111111010
In this example, we have a positive integer 5, which in binary is 000000000000000000000101. When we apply the Bitwise NOT operator (~), all bits are flipped, resulting in the binary representation of -7.
Binary Representation
To better understand how the Bitwise NOT operator works, let's explore binary numbers. Every integer between -2^31 and 2^31-1 can be represented as a 32-bit signed integer in JavaScript. The most significant bit (MSB) is used for the sign, while the remaining bits represent the magnitude of the number.
In the case of positive numbers, all bits except for the MSB are set to 0 or 1, depending on the value of the number. For negative numbers, the MSB is set to 1, and the remaining bits represent the absolute value of the number in 2's complement notation.
Two's Complement
Two's complement is a way of representing negative integers using binary notation. To find the two's complement of a positive integer, we first write its binary representation, then flip all the bits and add 1 to the result. For example:
const a = 3; // binary: 000000000000000000000011
console.log(~a + 1); // output: -4, binary: 111111111111111111111100
In this example, we find the bitwise complement of 3, then add 1 to get the two's complement representation of -4.
Hexadecimal Representation
Hexadecimal (base-16) is another common way to represent binary numbers. Each hexadecimal digit corresponds to a combination of four binary digits, or bits. The hexadecimal digits 0 through 9 correspond directly to their decimal values, while A, B, C, D, E, and F correspond to the decimal values 10 through 15.
Hexadecimal representation can be useful for working with binary numbers in JavaScript, as it allows you to easily read and write binary data using hexadecimal literals.
Worked Example
Let's work through an example that demonstrates the use of the Bitwise NOT operator:
const a = 5; // binary: 000000000000000000000101
const b = -3; // binary: 111111111111111111111101, but in JavaScript, it's represented as 2147483359 (2^31 - 3)
const c = ~a; // bitwise complement of 'a'
const d = ~b; // bitwise complement of 'b'
console.log(c); // output: -7, binary: 111111111111111111111010
console.log(d); // output: 2, binary: 000000000000000000000010
In this example, we first define three variables a, b, and c. We then use the Bitwise NOT operator (~) to find the bitwise complement of a and store it in c. Similarly, we find the bitwise complement of b and store it in d. The output shows that the Bitwise NOT operator correctly flips all the bits in the binary representation of both numbers.
Common Mistakes
- Forgetting to use the tilde (
~) symbol: This is the most common mistake when working with the Bitwise NOT operator. Make sure you use the tilde symbol instead of a minus sign or any other operator.
- Confusing signed and unsigned integers: Remember that the Bitwise NOT operator works on both signed and unsigned integers, but the result may be different depending on the sign of the original number. For positive numbers, the Bitwise NOT operator will flip all bits, while for negative numbers, it will flip all bits except for the MSB.
- Misunderstanding binary and hexadecimal representation: It's important to understand how binary and hexadecimal numbers are represented in JavaScript, as this can help you better understand how the Bitwise NOT operator works.
- Neglecting to handle edge cases: When working with the Bitwise NOT operator, it's essential to consider edge cases such as zero and the maximum and minimum signed integers in JavaScript. For example, the result of applying the Bitwise NOT operator on zero is itself, while the result of applying it on the maximum signed integer (2^31 - 1) is the minimum signed integer (-2^31).
- Incorrectly assuming that the Bitwise NOT operator has higher precedence than other operators: The Bitwise NOT operator has lower precedence than arithmetic and logical operators, so you should use parentheses to ensure proper evaluation of expressions involving multiple operators.
Practice Questions
- Write a function that takes an integer
nas input and returns its bitwise complement using the Bitwise NOT operator (~).
function bitwiseComplement(n) {
return ~n;
}
console.log(bitwiseComplement(5)); // output: -7
console.log(bitwiseComplement(-3)); // output: 2
- Write a function that determines whether a number is odd or even using the Bitwise NOT operator (
~).
function isOdd(n) {
return n & 1 !== 0;
}
console.log(isOdd(5)); // output: true
console.log(isOdd(6)); // output: false
- Write a function that swaps the bits of two integers using the Bitwise XOR and AND operators (
^and&).
function swapBits(a, b) {
const aCopy = a & ~(~0 << 32); // copy the lower 32 bits of 'a'
const bCopy = b & ~(~0 << 32); // copy the lower 32 bits of 'b'
return (a >> 32) | (bCopy << 32) | (aCopy << 32) | (b >> 32);
}
console.log(swapBits(1, 2)); // output: 2, binary: 000000000000000000000010, original binary of '1': 000000000000000000000001
- Write a function that checks if a number is a power of two using the Bitwise AND operator (
&) and the XOR operator (^).
function isPowerOfTwo(n) {
return n > 0 && ((n & (n - 1)) === 0);
}
console.log(isPowerOfTwo(8)); // output: true
console.log(isPowerOfTwo(9)); // output: false
- Write a function that finds the bitwise AND of all numbers in an array using the Bitwise AND operator (
&) and the reduce method.
function findBitwiseAND(arr) {
return arr.reduce((acc, num) => acc & num);
}
console.log(findBitwiseAND([5, 1, 4])); // output: 0 (which is the bitwise AND of all numbers in the array)
FAQ
Q: Can I use the Bitwise NOT operator on floating-point numbers?
A: No, the Bitwise NOT operator (~) only works on integers in JavaScript. If you try to apply it to a floating-point number, you will get a syntax error.
Q: How can I convert a binary number to its hexadecimal representation using JavaScript?
A: You can use the toString(16) method to convert a binary number (represented as a string of 0s and 1s) to its hexadecimal representation. Here's an example:
const binary = "1010";
const hexadecimal = parseInt(binary, 2).toString(16);
console.log(hexadecimal); // output: a
Q: How can I convert a hexadecimal number to its binary representation using JavaScript?
A: You can use the toString(2) method to convert a hexadecimal number (represented as a string containing hexadecimal digits) to its binary representation. Here's an example:
const hexadecimal = "a";
const binary = parseInt(hexadecimal, 16).toString(2);
console.log(binary); // output: 1010
Q: How can I check if a number is a power of two using the Bitwise AND operator (&) and the XOR operator (^)?
A: You can use the following function to determine if a number is a power of two:
function isPowerOfTwo(n) {
return n > 0 && ((n & (n - 1)) === 0);
}
console.log(isPowerOfTwo(8)); // output: true
console.log(isPowerOfTwo(9)); // output: false
In this function, we first check if the number n is greater than zero, as a power of two must be positive. Then, we use the Bitwise AND operator (&) to compare the number with itself minus one. If the result is zero, it means that all but the least significant set bit are cleared, indicating that the number is a power of two.
Q: How can I find the maximum and minimum signed integers in JavaScript?
A: You can find the maximum signed integer by using the Number.MAX_SAFE_INTEGER constant, which represents the largest safe integer that can be represented without losing precision. For the minimum signed integer, you can use the bitwise complement of the maximum signed integer and subtract 1:
console.log(Number.MAX_SAFE_INTEGER); // output: 9007199254740991
const minSignedInteger = ~Number.MAX_SAFE_INTEGER + 1;
console.log(minSignedInteger); // output: -9007199254740992
In this example, we first print the maximum safe integer using the Number.MAX_SAFE_INTEGER constant. Then, we find the bitwise complement of the maximum signed integer and add 1 to get the minimum signed integer.