6

What does this code mean and what are other ways accomplish the same without using bit shifting?

if ($n & ($n - 1))
Alix Axel
  • 151,645
  • 95
  • 393
  • 500

3 Answers3

18

That formula checks to see whether a number is a power of 2 (if your condition as written is true, then the number is not a power of two).

Stated another way, your test checks to see whether there is more than one "1" bit set in the binary representation of $n. If there is zero or only one bit set, then your test will be false.

It is by far the most efficient way to determine that property.

Community
  • 1
  • 1
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 1
    Greg, the question is, essentially, an adaptation that tests to see if a number isn't a power of two. Without `== 0` PHP takes any non-zero value as true. – Robert K Oct 11 '09 at 19:27
  • Yes, I thought the logical negation would be clear. Nevertheless, I have amended my answer to make that explicit. – Greg Hewgill Oct 11 '09 at 19:29
  • Well, it isn't negation at first glance (that would be `!= 0`), and my impression of eyze is that he's on a beginner's level. – Robert K Oct 11 '09 at 19:34
  • that's clever, i haven't seen this trick before. i had to do some math in my head to validate that this would work. :) – Kip Oct 11 '09 at 20:09
  • It's one of those "Old C Hacker's Tricks", except it should be `$n ^ ($n-1)`, and it's used to find the smallest '1' bit of n. As it is written, it'll group 0 with all of your powers of two. Of course, my version will show '0' as being full of ones - but then, having more than one '1' could be seen as a useful way to show that there wasn't any '1' in the original number. I hope this helps. – BMeph Jul 01 '10 at 19:13
  • Just to make thing a little clearer, the '^' sign in the formula above is supposed to be the eXclusive-OR (XOR) sign, which if you don't know it, is like a one-bit version of "!=" – BMeph Jul 01 '10 at 19:14
5

First, this code is valid PHP, so your title is poor.

Second, the binary arithmetic going on looks something like this:

42 = 101010
   &
41 = 101001
-----------
40 = 101000

Like Greg states this is the fastest way to check for a power of 2 number, but the code you've given checks to see if the number is not a power of 2. This can easily be ascertained by PHP's policy of: any non-null/non-zero value is true.

Robert K
  • 30,064
  • 12
  • 61
  • 79
0

When we use ($n & ($n - 1)) then it converts $n & ($n-1) to its binary values and does binary AND operation. Example

  3 = 0011
  4 = 0100
  5 = 0101

  3 = 0011
       &
  4 = 0100
------------
       0

  4 = 0100
       &
  5 = 0101
-----------
       100

To check if given number is power of 2 or not we alway use formulae ($n & ($n - 1) == 0) which means ANDing of $n & $n-1 is equals to 0 or not.

Online AND Operation Calculator

ViShU
  • 49
  • 8