-1

I've came across bitwise operators, and they really seem odd to me. Just wanted to get clarifications on two questions that I don't fully understand. The first piece of code is:

x = raw_input('Enter a digit: ')
print 'x is %s' % ('Even', 'Odd')[x & 1]

The question is the following - How does it exactly evaluates to 'Even' if I enter an even digit, and how does it pick the first element in parenthesis after evaluation?

On top of the that, can you please explain this piece of code:

if a[i-1] & 1 and a[i] & 1:
    do some stuff

Thank you all

novice
  • 19
  • 1
  • 1
  • 2
  • 2
    It doesn't evaluate to "even". That code doesn't even work. – Daniel Roseman Sep 10 '15 at 08:18
  • 1
    Not speaking to the code, but the odd/even. No even numbers have bit 0 (zero) set. The only values that have bit 0 set, are odd. – Brian Tiffin Sep 10 '15 at 08:23
  • In Python 2, `raw_input` returns a _string_... You won't get the user's input as an integer until you do something like `x = int(x)`. (Note to self: read the answers before commenting. [unwind's answer](http://stackoverflow.com/a/32496647/4116239) already addressed this.) – Kevin J. Chase Sep 10 '15 at 09:06

2 Answers2

2

Bitwise operations work on binary representations of your integer numbers.

if a[i-1] & 1 and a[i] & 1:
    do some stuff

Checks if both the entries at positions i and i-1 are odd numbers. This is realized by checking if the rightmost (least significant) bit of the numbers is 1. Take 42 and 23 as an example:

>>> bin(42)
'0b101010'
>>> bin(23)
 '0b10111'
>>> bin(1)
     '0b1'

Now you can apply a bitwise AND with one to both numbers. This operator returns a binary number which has a 1 on those positions, where the first AND the second input number have a 1-bit (and only there). Shorter numbers are padded with leading zeros:

  binary   decimal

  101010 = 42
& 000001 =  1
--------
  000000 =  0

   10111 = 23
&  00001 =  1
--------
   00001 =  1

So basically this is another way of doing:

if a[i-1]%2 == 1 and a[i]%2 == 1:
    do some stuff
m00am
  • 5,910
  • 11
  • 53
  • 69
1

Your code is broken, since it applies &, the bitwise AND, to x which holds a string. Here's what I got when I tried your code in Python 2.x:

Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> x=raw_input("enter a digit")
enter a digit4
>>> x
'4'
>>> x&1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'str' and 'int'

You need to parse it as integer:

print "x is %s" % ("even", "odd")[int(x) & 1]

This works by "masking" out the right-most bit of x using & 1. This will be set if the number is odd, and clear if it's even. The resulting number (0 or 1) is used to index into the pair ("even", "odd").

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Correct me if I'm wrong, but I think the code will work fine (at least on python 2) due to 0 having an ASCII code of 48? – Basic Sep 10 '15 at 08:23
  • 1
    @Basic I tried being more clear. Do you feel corrected? :) – unwind Sep 10 '15 at 08:25
  • 1
    No, strings (including single character ones) are never automatically converted to numbers. While you can use the fact that odd digits in ASCII have odd ordinals, you still need to convert to those using ord(). – Yann Vernier Sep 10 '15 at 08:43