In Java right rotation is done using:
(bits >>> k) | (bits << (Integer.SIZE - k))
But how to do similar thing in Python?
I tried to do (as described here):
n = 13
d = 2
INT_BITS = 4
print(bin(n))
print(bin((n >> d)|(n << (INT_BITS - d)) & 0xFFFFFFFF))
Output:
0b1101
0b110111
But I could not interpret this as a right rotation.
Also is it possible to perform the rotation by excluding leading zeroes, for example:
rightRotation of (...0001101) = 1110 not 1000...110
It is my mistake, if you want to change INT_BITS to 4 you also need to change 0xFFFFFFFF to 0xF (one hex equals 4-bits):
n = 13
d = 2
INT_BITS = 4
print(bin(n))
print(bin((n >> d)|(n << (INT_BITS - d)) & 0xF))
will output:
0b1101
0b111
Related
I had a string of int as a result of converting text to int. Here is its code in python:
def mix(data):
b = len(data)*8
m = bytes_to_long(data)
c = 0
for i in range(b//2):
if (m >> i) & 1:
c ^= m >> (b//2) << i
return c
So now, I had to make an "unmix" function to decode my result to its origin. But I'm still struggling with those Binary Shift Operators. Can you guys help me, please?
Is there a fast possibility to reverse a binary number in python?
Example: I have the number 11 in binary 0000000000001011 with 16 Bits. Now I'm searching for a fast function f, which returns 1101000000000000 (decimal 53248). Lookup tables are no solutions since i want it to scale to 32Bit numbers. Thank you for your effort.
Edit:
Performances. I tested the code for all 2^16 pattern several times.
winner are the partially look up tables: 30ms
2nd int(format(num, '016b')[::-1], 2) from the comments: 56ms
3rd x = ((x & 0x00FF) << 8) | (x >> 8): 65ms
I did not expect my approach to be so horribly slow but it is.
approx. 320ms. Small improvement by using + instead of | 300ms
bytes(str(num).encode('utf-8')) fought for the 2nd place but somehow
the code did not provide valid answers. Most likely because I made a
mistake by transforming them into an integer again.
thank you very much for your input. I was quite surprised.
This might be faster using small 8-bit lookup table:
num = 11
# One time creation of 8bit lookup
rev = [int(format(b, '08b')[::-1], base=2) for b in range(256)]
# Run for each number to be flipped.
lower_rev = rev[num & 0xFF] << 8
upper_rev = rev[(num & 0xFF00) >> 8]
flipped = lower_rev + upper_rev
I think you can just use slicing to get what you are looking for:
b=bytes('0000000000001011'.encode('utf-8'))
>>> b
b'0000000000001011'
>>> b[::-1]
b'1101000000000000'
There's this, but in Python it seems slower than Matthias' proposed int->str->int solution.
x = ((x & 0x5555) << 1) | ((x & 0xAAAA) >> 1)
x = ((x & 0x3333) << 2) | ((x & 0xCCCC) >> 2)
x = ((x & 0x0F0F) << 4) | ((x & 0xF0F0) >> 4)
x = ((x & 0x00FF) << 8) | (x >> 8)
My current approach is to access the bits via bit shifting and mask and to shift them in the mirror number until they reach their destination. Still I have the feeling that there is room for improvement.
num = 11
print(format(num, '016b'))
right = num
left = 0
for i in range(16):
tmp = right & 1
left = (left << 1 ) | tmp
right = right >> 1
print(format(left, '016b'))
I have a number like 0x5423 where I want to extract 4 values:
a = 0x5 # 15 downto 12
b = 0x42 # 11 downto 3
c = 0x3 # 3 downto 2
d = 0x00 # 1 downto 0
I discovered the module bitstrings that looks great. Unfortunately, for an unknown reason, the bits are numbered from the right.
This is bad because if a add some upper bits like 0xA5423 my extraction won't work anymore:
field = bitstrings.BitArray('0x5423')
a = field[0:4].uint
b = field[4:12].uint
c = field[12:14].uint
d = field[14:16].uint
How can I properly extract my bitfields without complex arithmetic manipulations such as:
b = (a >> 4) & 0xFF
Ideally I would have:
b = field.range(11, 4)
Convert the string to 0x#### format before pass to bitstring.BitArray:
>>> n = '0xA5423'
>>> n = '0x{:04x}'.format(int(n, 16) & 0xffff) # => '0x5423'
>>> field = bitstring.BitArray(n)
>>> field[0:4].uint
5
>>> field[4:12].uint # 0x42 == 66
66
>>> field[12:14].uint
0
>>> field[14:16].uint
3
UPDATE another solution that does not depend on bitstring, and count from left(according to OP):
Convert the number into binary format:
>>> n = '0xA5423'
>>> n = format(int(n, 16), '016b')[::-1] # reversed
>>> n
'11000100001010100101'
>>> int(n[0:2][::-1], 2) # need to reverse again to get proper value
3
>>> int(n[2:4][::-1], 2)
0
>>> int(n[4:12][::-1], 2)
66
>>> int(n[12:16][::-1], 2)
5
I want to realize IDEA algorithm in Python. In Python we have no limits for variable size, but I need limit bit number in the integer number, for example, to do cyclic left shift. What do you advise?
One way is to use the BitVector library.
Example of use:
>>> from BitVector import BitVector
>>> bv = BitVector(intVal = 0x13A5, size = 32)
>>> print bv
00000000000000000001001110100101
>>> bv << 6 #does a cyclic left shift
>>> print bv
00000000000001001110100101000000
>>> bv[0] = 1
>>> print bv
10000000000001001110100101000000
>>> bv << 3 #cyclic shift again, should be more apparent
>>> print bv
00000000001001110100101000000100
An 8-bit mask with a cyclic left shift:
shifted = number << 1
overflowed = (number & 0x100) >> 8
shifted &= 0xFF
result = overflowed | shifted
You should be able to make a class that does this for you. With a bit more of the same, it can shift an arbitrary amount out of an arbitrary sized value.
The bitstring module might be of help (documentation here). This example creates a 22 bit bitstring and rotates the bits 3 to the right:
>>> from bitstring import BitArray
>>> a = BitArray(22) # creates 22-bit zeroed bitstring
>>> a.uint = 12345 # set the bits with an unsigned integer
>>> a.bin # view the binary representation
'0b0000000011000000111001'
>>> a.ror(3) # rotate to the right
>>> a.bin
'0b0010000000011000000111'
>>> a.uint # and back to the integer representation
525831
If you want a the low 32 bits of a number, you can use binary-and like so:
>>> low32 = (1 << 32) - 1
>>> n = 0x12345678
>>> m = ((n << 20) | (n >> 12)) & low32
>>> "0x%x" % m
'0x67812345'
hi i am new in python just started learning with python i got a task in which i need to store "1" byte of integer into different bits just like RGB the value are store in that can any one would write a small program for me and explain that ,please i need a help
Thankyou
I'll assume this question is legitimate and appropriate for the forum..
# To Encode:
r = 1
g = 2
b = 3
rgb = r << 16 | g << 8 | b
#To extract:
r = (rgb >> 16) & 0xFF
g = (rgb >> 8) & 0xFF
b = rgb & 0xFF
To convert a number to a list of it's binary digits: list(bin(number))[2:]