0

I went through a simple problem, but its solution got me confused.

function modifyArray(nums) {
    // i & 1 will be 1, or true, if 'i' is odd
    return nums.map(i => (i & 1) ? i * 3 : i * 2);
}


console.log(modifyArray([0, 1, 2, 3, 4, 5]));

In the above code,(i&1) returns true or 1 if i is an odd number.

How does this work, can anyone please explain?

Not A Bot
  • 2,474
  • 2
  • 16
  • 33
  • 4
    All numbers but zero are [truthy](https://stackoverflow.com/questions/5515310/is-there-a-standard-function-to-check-for-null-undefined-or-blank-variables-in/5515349#5515349) – JavaScript Jul 13 '21 at 14:30
  • 4
    [bitwise AND](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND) – apple apple Jul 13 '21 at 14:30
  • 3
    The binary representation of any odd number ends with `1` while that of any even number ends with `0`. The binary representation of `1` is many `0`s and a `1`. `&` is the Bitwise AND Operator so it calculates the AND of each bit. For any other positions because one side is `0` you always get zero. But for the last bit one side is `1` so it'll produce `1` when other side ends with `1` too, and `1` is truthy. Else it produces `0` and it is falsy. – daylily Jul 13 '21 at 14:34

5 Answers5

1

The expression (n & 1) will always return true for positive odd numbers, since the Least Significant Bit (LSB) will be set for these values.

So the result will be

         xxxx1
AND (&)  00001
--------------
Result   00001

The result will always be 1, which is Truthy

You can demonstrate this by logging the binary representation of each value to the console:

let nums = Array.from({ length: 10}, (v,k) => k + 1);
console.log("Nums:", JSON.stringify(nums))
console.log("Nums.map (binary):", JSON.stringify(nums.map(num => num.toString(2).padStart(4, '0'))))
console.log("Nums.map (binary, LSB):", JSON.stringify(nums.map(num => +num.toString(2).slice(-1))))
console.log("Nums.map (num & 1):", JSON.stringify(nums.map(num => (num & 1))))
Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
0

As the comments already said, you are doing an bitwise AND. Think of the binary representation of each number and compare each digit with an AND to get the resulting digit. Here are some examples:

1&1 (both values have a binary 1 in the last column)

  0001
& 0001
= 0001

2&1 (there is not a single 1 in the same column for both numbers)

  0010
& 0001
= 0000

5&1 (both values have a binary 1 in the last column)

  0101
& 0001
= 0001

6&1 (there is not a single 1 in the same column for both numbers)

  0110
& 0001
= 0000
Jens
  • 495
  • 1
  • 6
  • 28
0

Bit operators (&, |, ~, ...) work on 32 bits numbers. Any numeric operand in the operation is converted into a 32 bit number. The result is converted back to a JavaScript number. For example

x = 5 & 1 is same as 0101 & 0001 which is equal to 0001 and in decimal it is 1

You may refer to binary equivalent of numbers here https://www.javatpoint.com/binary-numbers-list

Amit Kumar
  • 15
  • 6
0

The Array in Binary:

0 = 0000
1 = 0001
2 = 0010
3 = 0011
4 = 0100
5 = 0101

AND Results:

0 & 1 => 0000 AND 0001 = 0000 => False
1 & 1 => 0001 AND 0001 = 0001 => True
2 & 1 => 0010 AND 0001 = 0000 => False
3 & 1 => 0011 AND 0001 = 0001 => True
4 & 1 => 0100 AND 0001 = 0000 => False
5 & 1 => 0101 AND 0001 = 0001 => True

i & 1 will always look at the first bit and see if it is a 0 or a 1. So all odds will have a 0 while all evens will have a 1

Philipp Panik
  • 254
  • 1
  • 4
  • 15
0

& is bitwise and. Everything is a bit under the hood.

Examples for numbers up to 3 digits:

0 = 000
1 = 001
2 = 010
3 = 011
4 = 100
7 = 111

When we do bitwise and of 1 and say, 3, we are doing AND between each digit of 001 and 011, which returns 1. For, 100 and 001 it returns 0.

This bitwise and is good shortcut to find odd numbers as the last digit of bitwise representation of every odd number is 1.

Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39