-1

I came across this piece of code on reddit

1 - ((num & 1) << 1) as i32

This code returns 1 for even numbers and -1 for odd numbers.

It takes less instructions than other ways of calculating the same thing, and is presumably, quite fast. So, how does it work? (A step-by-step breakdown would be helpful)

Note: I found What is the fastest way to find if a number is even or odd?, but don't understand how that works either.

jub0bs
  • 60,866
  • 25
  • 183
  • 186
Naitik Mundra
  • 418
  • 3
  • 14
  • Have you read about bitwise operators? Try writing down the effects of each operation, outside to inside, using e.g. 0b00000001 for `num`. – hnefatl Dec 09 '22 at 19:35
  • @hnefatl, I actually dont understand how 1-() works on u32. – Naitik Mundra Dec 09 '22 at 19:45
  • It doesn't check the parity of `num`; it computes `pow(-1, num)`. The parity check is just `num & 1`; the rest turns that into `-1` or `1` as appropriate. – BallpointBen Dec 09 '22 at 22:47

1 Answers1

2

Let's break this down from the inside out.

  1. num & 1

This "masks" all but the least significant bit using a bitwise and. Since the least significant bit is the "ones" place, it will evaluate to 1 if the number is odd or 0 if the number is even.

  1. (result1) << 1

This bitshifts that left by 1. This has the effect of multiplying by two. If num was odd, this will evaluate to 2 or still 0 if num was even. (0 * 2 = 0)

  1. (result2) as i32

This casts the resulting unsigned integer (2 or 0) into a signed integer, allowing us to subtract it in the next operation. This is only for the compiler, it has no effect on the value in memory.

  1. 1 - result3

This subtracts the previous number from 1. If num was even, we get 1 - 0 which results in a final answer of 1. If num was odd, we get 1 - 2 which results in a final answer of -1.

PitaJ
  • 12,969
  • 6
  • 36
  • 55