Left shift but replace the shifted bits with ones - python

In Python the << operator does the following:
Returns x with the bits shifted to the left by y places (and new bits on the right-hand-side are zeros). This is the same as multiplying x by 2**y.
I want to have another version where it fills 1 on the new bits. Is there a built in function for this, if not how do I write it?

Is x = (x << y) | ((1 << y) - 1) what you're looking for?
First, we shift x left y bits:
x = 21
y = 2
bin(x) == 10101 (in binary)
x << y == 1010100
Then, the number ((1 << y) - 1) gives us a number with only the y lowest bits set to 1,
e.g.
1 << 2 == 100
(1 << 2) - 1 == 011
Finally, we or them to get 1010100 | 11 == 1010111.

There's no such function built in, or, for that matter, available in any extension library I know of.
It's pretty easy to do yourself, though. Say the int is n and you want to shift it left by s bits.
First flip all the bits of n (change all 0 bits to 1, and all 1 bits to 0). Then shift left by s. That adds s 0 bits on the right. Then flip the bits again. The new trailing 0 bits are changed to 1 bits, and the original bits of n are restored.
>>> n = 5
>>> bin(n)
'0b101'
>>> ~(~n << 6)
383
>>> bin(_)
'0b101111111'

Related

an easy way to choose bit(s) form a word

Is there an easy way to choose bit(s) form a word ?
I prefer to use with built in library.
For example,
I read the data from binary file (I read 32bit each time because I work with words)
num = 128 (1000 0000 )
I want: num[7:6] = 10 in binary = 2
I did it with ('shift' and 'and') or int(bin(128)[2:][::-1][6:8][::-1],2)
You could use bitwise operators. e.g,
(((1 << 8) - 1) & num) >> 6
In general, for bits a to b (higher bits to lower, 0-indexed),
(((1 << (a+1)) - 1) & num) >> b
Explanation:
Say num is 121 = 0111 1001, and we want bit 4 to bit 2 (0-indexed). i.e, 110 or 6. So a = 4, b = 2.
((1 << (a+1)) - 1) is just 111...a times. Doing & with this helps us pick the last "a" bits. e.g, any number & 11 will pick its last 2 bits. A number & 111 will pick the last 3 and so on.
So ((1 << (a+1)) - 1) & num is just the last a bits of num.
>> b drops the last b bits.
Therefore, together,
(((1 << (a+1)) - 1) & num) >> b has the effect of picking the last a bits from num, then dropping the last b bits. So together, it will return bits in the a to b range

Python convert int to unsigned short then back to int

A coordinate x,y is encoded in a integer using this function
# Convert X Y position to MAP file index
def index_from_xy(x, y):
return (y - 16) << 16 | (x & 65535)
It seems that x has been converted into an unsigned short.
x and y are within the range [-32767 32767]
What is the function that will convert the index into a x, y tuple ?
All python integers are long under the hood (unless you're playing with bigger numbers).
To extract x and y, just reverse the steps of the above function.
def int_to_signed_short(value):
return -(value & 0x8000) | (value & 0x7fff)
def xy_from_index(index):
x, y = index & 65535, (index >> 16) + 16
return map(int_to_signed_short, [x, y])
In more detail, your function takes the two numbers and shifts them in binary so they don't overlap with each other.
x & 65535 only keeps the 16 rightmost bits of x, since 65535 is 16 1s in binary. Read more about bitwise AND.
(y - 16) << 16 shifts the number y - 16 16 bits to the left. So if your number was XXXXX in binary, it will become XXXXX0000000000000000. Read more about bitwise shift.
A | B will OR the bits of both numbers. Since A has 16 0s to the right and B is at most 16 bits long, A and B will not interfere with each other's bits. Read more about bitwise OR
Once you understand that, it should become clear how my function is the inverse of this.
Example
>>> index = index_from_xy(1234, 5678)
>>> index
371066066
>>> xy_from_index(index)
(1234, 5678)

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

Complement of XOR

What is the most efficient algorithm for finding ~A XOR B? (Note that ~ is the complement function, done by reversing each 1 bit into 0 and each 0 into 1 bit, and XOR is the exclusive or function)
For example, ~4 XOR 6 = ~010 = 101 = 5 and ~6 XOR 9 = ~1111 = 0
Here's an answer that takes into account the number of bits needed to store your integers:
def xnor(a, b):
length = max(a.bit_length(), b.bit_length())
return (~a ^ b) & ((1 << length) - 1)
I can't think of a situation where this is better than just ~a ^ b however. And it almost certainly makes no sense for negative numbers.
The only problem here is that ~ returns a negative number for a positive input, and you want a positive result limited to the significant bits represented in the inputs.
Here's a function that can generate a mask of bits that are needed in the result:
def mask(n):
n = abs(n)
shift = 1
while n & (n + 1) != 0:
n |= n >> shift
shift *= 2
return n
And here's how to use it:
print (~a ^ b) & mask(a | b)
You can simply use ==.
A XNOR B is same as == operator because:
A B NXOR
F F T
F T F
T F F
T T T

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.

Categories

Resources