>> operator in Python - python

What does the >> operator do? For example, what does the following operation 10 >> 1 = 5 do?

It's the right bit shift operator, 'moves' all bits once to the right.
10 in binary is
1010
shifted to the right it turns to
0101
which is 5

>> and << are the Right-Shift and Left-Shift bit-operators, i.e., they alter the binary representation of the number (it can be used on other data structures as well, but Python doesn't implement that). They are defined for a class by __rshift__(self, shift) and __lshift__(self, shift).
Example:
>>> bin(10) # 10 in binary
1010
>>> 10 >> 1 # Shifting all the bits to the right and discarding the rightmost one
5
>>> bin(_) # 5 in binary - you can see the transformation clearly now
0101
>>> 10 >> 2 # Shifting all the bits right by two and discarding the two-rightmost ones
2
>>> bin(_)
0010
Shortcut: Just to perform an integer division (i.e., discard the remainder, in Python you'd implement it as //) on a number by 2 raised to the number of bits you were shifting.
>>> def rshift(no, shift = 1):
... return no // 2**shift
... # This func will now be equivalent to >> operator.
...

You can actually overloads right-shift operation(>>) yourself.
>>> class wierd(str):
... def __rshift__(self,other):
... print self, 'followed by', other
...
>>> foo = wierd('foo')
>>> bar = wierd('bar')
>>> foo>>bar
foo followed by bar
Reference: http://www.gossamer-threads.com/lists/python/python/122384

Its the right shift operator.
10 in binary is 1010 now >> 1 says to right shift by 1, effectively loosing the least significant bit to give 101, which is 5 represented in binary.
In effect it divides the number by 2.

See section 5.7 Shifting Operations in the Python Reference Manual.
They shift the first argument to the
left or right by the number of bits
given by the second argument.

Related

Why does ~True return the value -2 in Python? [duplicate]

I'm a little confused by the ~ operator. Code goes below:
a = 1
~a #-2
b = 15
~b #-16
How does ~ do work?
I thought, ~a would be something like:
0001 = a
1110 = ~a
why not?
You are exactly right. It's an artifact of two's complement integer representation.
In 16 bits, 1 is represented as 0000 0000 0000 0001. Inverted, you get 1111 1111 1111 1110, which is -2. Similarly, 15 is 0000 0000 0000 1111. Inverted, you get 1111 1111 1111 0000, which is -16.
In general, ~n = -n - 1
The '~' operator is defined as:
"The bit-wise inversion of x is defined as -(x+1). It only applies to integral numbers."Python Doc - 5.5
The important part of this sentence is that this is related to 'integral numbers' (also called integers). Your example represents a 4 bit number.
'0001' = 1
The integer range of a 4 bit number is '-8..0..7'. On the other hand you could use 'unsigned integers', that do not include negative number and the range for your 4 bit number would be '0..15'.
Since Python operates on integers the behavior you described is expected. Integers are represented using two's complement. In case of a 4 bit number this looks like the following.
7 = '0111'
0 = '0000'
-1 = '1111'
-8 = '1000'
Python uses 32bit for integer representation in case you have a 32-bit OS. You can check the largest integer with:
sys.maxint # (2^31)-1 for my system
In case you would like an unsigned integer returned for you 4 bit number you have to mask.
'0001' = a # unsigned '1' / integer '1'
'1110' = ~a # unsigned '14' / integer -2
(~a & 0xF) # returns 14
If you want to get an unsigned 8 bit number range (0..255) instead just use:
(~a & 0xFF) # returns 254
It looks like I found simpler solution that does what is desired:
uint8: x ^ 0xFF
uint16: x ^ 0xFFFF
uint32: x ^ 0xFFFFFFFF
uint64: x ^ 0xFFFFFFFFFFFFFFFF
You could also use unsigned ints (for example from the numpy package) to achieve the expected behaviour.
>>> import numpy as np
>>> bin( ~ np.uint8(1))
'0b11111110'
The problem is that the number represented by the result of applying ~ is not well defined as it depends on the number of bits used to represent the original value. For instance:
5 = 101
~5 = 010 = 2
5 = 0101
~5 = 1010 = 10
5 = 00101
~5 = 11010 = 26
However, the two's complement of ~5 is the same in all cases:
two_complement(~101) = 2^3 - 2 = 6
two_complement(~0101) = 2^4 - 10 = 6
two_complement(~00101) = 2^5 - 26 = 6
And given that the two's complement is used to represent negative values, it makes sense to consider ~5 as the negative value, -6, of its complement.
So, more formally, to arrive at this result we have:
flipped zeros and ones (that's equivalent to taking the ones' complement)
taken two's complement
applied negative sign
and if x is a n-digit number:
~x = - two_complement(one_complement(x)) = - two_complement(2^n - 1 - x) = - (2^n - (2^n - 1 - x)) = - (x + 1)

What is the interpreter really seeing and executing for bitwise operators?

I am trying to understand bitwise operators in Python 2.7 (<<, >>, &, |, ~ and ^), so my question is: what is the interpreter really seeing and executing? When:
>>> 3 >> 0
3
>>> 3 >> 1
1
and why
>>> 3 >> 2
0
and after that if you increment the second number by one the answer will continue to be 0.
They treat it as if it were a string of bits, written in twos-complement binary. But I do not understand what happens here.
Have a look at the binary representation of these numbers and imagine that there are infinite zeroes to the left:
...0000011 = 3
Now, what >> does is it shifts the binary representation to the right. This is the same as deleting the last digits:
If you shift by 0 places, nothing changes. Therefore, 3 >> 0 is 3.
If you shift by 1 place, you delete the last binary digit:
...0000011 >> 1 = ...000001 = 1
Therefore, 3 >> 1 is 1.
If you shift by 2 or more places, all of the binary ones will be deleted and you are left with only zeroes:
...0000011 >> 2 = ...00000 = 0
This is why 3 >> 2 (or more than 2) is always 0.

Variable assignment with ">>" and "&" operators

I've been trying to understand a Python script and I can't figure out what this assignment is doing:
data_byte2 = value >> 7 & 127
I've seen a kind of similar construct with the or operator but never with & and I have no idea at all what >> does (nothing's coming up on Google for it).
value >> 7 & 127
Is like writing:
(value >> 7) & 127 # see Python Operators Precedence
First you rightshift value by 7, then & result with 127.
127 in binary is 1111111, when you & with this number, you're clearing all bits on left of the number. For example, if you have 16 bit number:
1101011101111101
→
Shifting it 7 to the right will result in:
0000000110101110
& with 127 will keep only most right 8 bits:
0000000110101110
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
0000000001111111 & (127)
----------------
0000000000101110
>> is the right bit-shift operator, and & is bitwise AND.
This is easier to see if you look at numbers in binary form.
>>> format(13, "08b")
'00001101'
>>> format(13 >> 1, "08b")
'00000110'
You can see that the binary digits are right-shifted by one place (this is equivalent to a division by 2, so x >> y is equivalent to x // (2 ** y)). On that basis, x >> 7 means "shift x's bits seven places to the right", or "divide x by 128".
>>> format(10, "08b")
'00001010'
>>> format(7, "08b")
'00000111'
>>> format(10 & 7, "08b")
'00000010'
Here the output includes a 1 for every bit where both inputs have 1, 0 otherwise. Given that
>>> format(127, "08b")
'01111111'
x & 127 means "take the last seven bits of x".
As >> has higher operator precedence than &, the expression
value >> 7 & 127
means "divide value by 128 then take the last seven bits".
>> is right shift operator
>>> 3 >> 1
1
binary of 3 is 00011, now shift one bit towards right the so it will be 00001 so we get answer 1
>>> 3 >> 2
0
binary of 3 is 00011, now shift two bit towards the right, so it will be 0000, so output is 0

append 2 hex values in python

I am trying to append some hex values in python and I always seem to get 0x between the number. From what I searched, either this is not possible without converting it into a lit of values ?? I am not sure.
a = 0x7b
b = 0x80000
hex(a) + hex(b) = 0x7b0x80000
I dont want the 0x in the middle - I need, 0x7b80000. is there any other way to do this? If I convert to integer I get the sum of the two and converting it to hex is a different value than 0x7b80000
I don't think you want to "append" them. Doing integer arithmetic by using strings is a bad idea. I think you want to bit-shift a into the right place and OR them together:
>>> a = 0x7B
>>> b = 0x80000
>>>
>>> hex( (a<<20) | b )
'0x7b80000'
Perhaps if you were more specific about what these numbers are and what exactly you're trying to accomplish I could provide a more general answer.
You can use f-string formatting with Python 3:
>>> a = 0x7b
>>> b = 0x80000
>>> f'0x{a:x}{b:x}'
'0x7b80000'
This is a more generic way to append hex / int / bin values.
Only works for positive values of b.
a = 0x7b
b = 0x80000
def append_hex(a, b):
sizeof_b = 0
# get size of b in bits
while((b >> sizeof_b) > 0):
sizeof_b += 1
# align answer to nearest 4 bits (hex digit)
sizeof_b += sizeof_b % 4
return (a << sizeof_b) | b
print(hex(append_hex(a, b)))
Basically you have to find the highest set bit that b has.
Align that number to the highest multiple of 4 since that's what hex chars are.
Append the a to the front of the highest multiple of 4 that was found before.
It's been 7 years but the accepted answer is wrong and this post still appears in the first place in google searches; so here is a correct answer:
import math
def append_hex(a, b):
sizeof_b = 0
# get size of b in bits
while((b >> sizeof_b) > 0):
sizeof_b += 1
# every position in hex in represented by 4 bits
sizeof_b_hex = math.ceil(sizeof_b/4) * 4
return (a << sizeof_b_hex) | b
The accepted answer doesn't make sense (you can check it with values a=10, b=1a). In this solution, we search for the nearest divider of 4 - since every hex value is represented by 4 bits - and then move the first value this time of bits.

What is the double inequality (>>) sign in python? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python - '>>' operator
There's some code that does this:
x = n - 1 >> 1
I don't know if I have to provide more syntax, but what does the >> mean? I've been searching all over, but can't find any explanation.
Its a shift right logical, it is a bitwise operation that tells the number to shift in bits by that amount. In this case you are shifting by 1, which is equivalent to dividing by 2.
If you do not understand bitwise operations, a simple conversion for you to remember would be this.
x >> n
is equivalent to
x // (2**n)
It is the bitwise shift-to-right operator.
It shifts the bits of the integer argument to the right by the number on the right-hand side of the expression:
>>> 8 >> 2
2
or illustrated in binary:
>>> bin(0b1000 >> 2)
'0b10'
Your code example is actually doubly confusing as it mixes arithmetic and bitwise operations. It should use the '//' integer division operation instead:
x = (n - 1) // 2
x >> y
is equivalent to
x.__rshift__(y)
which, as others have said, is meant to be a bitshift.
>> is the bitwise right shift operator. This operator move all bits in the first operand right by the second operand.
So: a >> b = a // 2**b
Example:
36 in binary is 0b100100
36 >> 1 is 0b10010 (last binary digit or "bit" is removed) which is 18
36 >> 2 is 0b1001 (2 bits removed) which is 9
Note that the operator goes after addition. So the code does n-1 first, then right shift it by 1 bit (i.e. divides by 2).

Categories

Resources