Strange if statement

后端 未结 4 1434
甜味超标
甜味超标 2021-02-18 13:16

I found this strange if-statement in somebody else’s code:

if variable & 1 == 0:

I don\'t understand it. It should have two

相关标签:
4条回答
  • 2021-02-18 14:00

    The conditional is a bitwise operator comparison:

    >>> 1 & 1
    1
    >>> 0 & 1
    0
    >>> a = 1
    >>> a & 1 == 0
    False
    >>> b = 0
    >>> b & 1 == 0
    True
    

    As many of the comments say, for integers this conditional is True for evens and False for odds. The prevalent way to write this is if variable % 2 == 0: or if not variable % 2:

    Using timeit we can see that there isn't much difference in performance.

    n & 1("== 0" and "not")

    >>> timeit.Timer("bitwiseIsEven(1)", "def bitwiseIsEven(n): return n & 1 == 0").repeat(4, 10**6)
    [0.2037370204925537, 0.20333600044250488, 0.2028651237487793, 0.20192503929138184]
    
    >>> timeit.Timer("bitwiseIsEven(1)", "def bitwiseIsEven(n): return not n & 1").repeat(4, 10**6)
    [0.18392395973205566, 0.18273091316223145, 0.1830739974975586, 0.18445897102355957]
    

    n % 2("== 0" and "not")

    >>> timeit.Timer("modIsEven(1)", "def modIsEven(n): return n % 2 == 0").repeat(4, 10**6)
    [0.22193098068237305, 0.22170782089233398, 0.21924591064453125, 0.21947598457336426]
    
    >>> timeit.Timer("modIsEven(1)", "def modIsEven(n): return not n % 2").repeat(4, 10**6)
    [0.20426011085510254, 0.2046220302581787, 0.2040550708770752, 0.2044820785522461]
    

    Overloaded Operators:

    Both the % and & operators are overloaded.

    The bitwise and operator is overloaded for set. s.intersection(t) is equivalent to s & t and returns a "new set with elements common to s and t".

    >>> {1} & {1}
    set([1])
    

    This doesn't effect our conditional:

    >>> def bitwiseIsEven(n):
    ...   return n & 1 == 0
    
    >>> bitwiseIsEven('1')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in bitwiseIsEven
    TypeError: unsupported operand type(s) for &: 'str' and 'int'
    >>> bitwiseIsEven({1})
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in bitwiseIsEven
    TypeError: unsupported operand type(s) for &: 'set' and 'int'
    

    The modulo operator will also throw TypeError: unsupported operand type(s) for most non-ints.

    >>> def modIsEven(n):
    ...   return n % 2 == 0
    
    >>> modIsEven({1})
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in modIsEven
    TypeError: unsupported operand type(s) for %: 'set' and 'int'
    

    It is overloaded as a string interpolation operator for the old %-formatting. It throws TypeError: not all arguments converted during string formatting if a string is used for the comparison.

    >>> modIsEven('1')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in modIsEven
    TypeError: not all arguments converted during string formatting
    

    This won't throw if the string includes a valid conversion specifier.

    >>> modIsEven('%d')
    False 
    
    0 讨论(0)
  • 2021-02-18 14:01

    Your only concern is probably the operator &. It is a bitwise and which takes the binary format of the two operands and perform "logic and" on each pair of bits.

    For your example, consider the following:

    variable = 2  #0b0010
    if variable & 1 == 0:
        print "condition satisfied" # satisfied, 0b0010 & 0b0001 = 0
    
    variable = 5  #0b0101
    if variable & 1 == 0:
        print "condition satisfied" # not satisfied, 0b0101 & 0b0001 = 1
    

    Note:

    variable = 6  #0b0110
    if variable & 2 == 0:
        print "condition satisfied" # not satisfied, 0b0110 & 0b0010 = 2 (0b0010)
    
    0 讨论(0)
  • 2021-02-18 14:14

    This code just checks if the lowest bit of variable is a 0. Based on operator precedence this is:

    if (variable & 1) == 0:
    

    First AND the lowest bit with one (extract just the lowest bit), then check if it is 0.

    0 讨论(0)
  • 2021-02-18 14:23

    The & is a bitwise operator. It returns an integer with 1 bit for every bit of its two operands that are both 1, and 0 in all other places. For example:

    a = 10 # 0b1010
    b = 6  # 0b0110
    a & b  # 0b0010
    

    Now, if you have variable & 1, you're comparing variable against 0b1 which will only return 1 if that last digit in the binary representation is a 1, otherwise a 0.

    0 讨论(0)
提交回复
热议问题