By default the 'left shift' operation in Python ( << ) acts as an arithmetic shift and appends a 0 bit to the end of the bits representing the int.
For example:
100 << 1 returns 200
In the binary representation we can see that 100 = 0b1100100 (7 bits) and 100 << 1 = 0b11001000 (8 bits)
In Python 3 what is the best way to perform a logical left shift where the number of bits stays constant, but the values are shifted to the left one?
For example:
100 << 1 would return 72
In the binary representation 100 = 0b1100100 and 100 << 1 = 0b1001000
We've kept the same 7 bits, but just shifted to the left one and appended a 0 to the end.
You can use int.bitlength to get the number of bits required to represent the number, then and the result of the shift with (1 << bitlength) - 1 to restrict the result to that many bits:
def lls_const_bits(n):
return (n << 1) & ((1 << n.bit_length()) - 1)
print(lls_const_bits(100))
Output:
72
If you want to restrict the output to a fixed number of bits b, you would need to mask with (1 << b) - 1:
def lls_const_bits(n, b):
return (n << 1) & ((1 << b) - 1)
print(lls_const_bits(100, 7))
Output:
72
Related
For example, if I have an int with a length of 32 bits, how do I store value A in the first 16 bits, then store value B in bits 17-24, and value C in bits 25-32? And how can I get these three values out of an int?
Assuming that your values fit in the assigned bit counts, it's just a question of shifting them to make an int, and then unshifting and masking to get them back:
A = 34945
B = 49
C = 233
B_shift = 16
C_shift = 24
result = A + (B << B_shift) + (C << C_shift)
print(result)
resA = result & ((1 << B_shift) - 1)
resB = (result >> B_shift) & ((1 << (C_shift - B_shift)) - 1)
resC = result >> C_shift
print(resA, resB, resC)
When the if statement is true I want to sequentially set every bit in the left shift operation one at a time rather than setting all bits at once. Any idea on how I could implement this?
if (reg_test == arduino_reg7.value):
Reg_Value |= (0x1A << 20)
If I understand, you want to have `Reg_Value' be set to each of these in succession:
0bxxxx_xxxx_xxxx_xxxx_xxxx_xxxx
0bxxx1_xxxx_xxxx_xxxx_xxxx_xxxx
0bxx01_xxxx_xxxx_xxxx_xxxx_xxxx
0bx101_xxxx_xxxx_xxxx_xxxx_xxxx
0b1101_xxxx_xxxx_xxxx_xxxx_xxxx
Where the 'x' bits are left unmodified
I would suggest:
if (reg_test == arduino_reg7.value):
bval = 0x1A
for i in range(20,28):
Reg_Value |= (bval << 20) & (1 << (i+1))
This allows for any byte value (bval) to be placed in bits 20-27 one bit at a time, in ascending order. Any higher-order bits are also left unchanged.
You could simplify the (1 << (i+1)) to (1 << i) by changing the range to range(21, 29). But bits are typically numbered from 0, and this affects bits 20-27, not 21-28.
You could also change it to (2 << i) and leave the range, but I think that obscures what you're really doing -- though that's a personal preference. Unless timing is extremely critical, the extra +1 won't make a difference.
Assuming that your value of 0x1A is constant then you could simply create a list where each element represents one of the 3 bits. Then:
bits = [0x10 << 20, 0x8 << 20, 0x2 << 20]
if (reg_test == arduino_reg7.value):
for b in bits:
Reg_Value |= b
If 0x1A is not constant, then you could build your array of bits like this:
v = 0x1a # or some other 8-bit value
bits = []
b = 1
while v > 0:
if v & 1:
bits.append(b<<20)
b <<= 1
v >>= 1
I want to achieve the equivalent of the ISHFTC function in Fortran using python.
What is the best way to do this?
For example,
x = '0100110'
s = int(x, 2)
s_shifted = ISHFTC(s,1,7) #shifts to left by 1
#binary representation of s_shifted should be 1001100
My attempt based on Circular shift in c
def ISHFTC(n, d,N):
return (n << d)|(n >> (N - d))
However, this does not do what I want. Example,
ISHFTC(57,1,6) #57 is '111001'
gives 115 which is '1110011' whereas I want '110011'
Your attempted solution does not work because Python has unlimited size integers.
It works in C (for specific values of N, depending on the type used, typically something like 8 or 32), because the bits that are shifted out to the left are automatically truncated.
You need to do this explicitly in Python to get the same behaviour. Truncating a value to the lowest N bits can be done be using % (1 << N) (the remainder of dividing by 2N).
Example: ISHFTC(57, 1, 6)
We want to keep the 6 bits inside |......| and truncate all bits to the left. The bits to the right are truncated automatically, because the these are already the 6 least significant bits.
n |111001|
a = n << d 1|110010|
m = (1 << N) 1|000000|
b = a % m 0|110010|
c = n >> (N - d) |000001|(11001)
result = b | c |110011|
Resulting code:
def ISHFTC(n, d, N):
return ((n << d) % (1 << N)) | (n >> (N - d))
# ^^^^^^ a
# ^^^^^^ m
# ^^^^^^^^^^^^^^^^^ b
# ^^^^^^^^^^^^ c
>>> ISHFTC(57, 1, 6)
51
>>> bin(_)
'0b110011'
Is there a more efficient way of performing the following calculation? It works fine, but something tells me that x &= (1 << 8) - 1 ^ 1 << 3 can be written to avoid some calculations and increase speed.
def unset_mask(width, index):
return (1 << width) - 1 ^ 1 << index
x = 0b11111111
x &= unset_mask(8, 3)
assert x == 0b11110111
Actually, you don't need to state the width. Bigints behave the right way when you do this:
>>> bin(255 & ~(1 << 3))
'0b11110111'
>>> bin(65535 & ~(1 << 3))
'0b1111111111110111'
>>> bin(75557863725914323419135 & ~(1 << 3))
'0b1111111111111111111111111111111111111111111111111111111111111111111111110111'
It's because negative numbers have an "infinite" string of ones preceding them. So when you complement a positive number (which starts with an "infinte" string of zeros), you get a negative number (-(x + 1) to be exact). Just don't trust the bin representation of negative numbers; it doesn't reflect the actual bits in memory.
So you would rewrite unset_mask like so:
def unset_mask(index):
return ~(1 << index)
x = 0b11111111
x &= unset_mask(3)
print x == 0b11110111 # prints True
You can use this to clear a bit in x:
x &= ~(1 << index)
This will unset the bit:
x ^= 1 << 3 & x
In a function:
def unset_bit(x, n):
return 1 << n & x ^ x
def different(s):
x = len(s)
for i in range(1, 1 << x):
u.append([s[j] for j in range(x) if (i & (1 << j))])
It takes a list and makes different combinations
(a,b,c) = ((a,b,c),(a,b),(a,c) ...)
But what does the range do? From 1 to what. I don't understand the "<<"
and also, if (i & (1 << j)) what does this do? It checks if i and 2 to the power of j? Doesn't make any sense to me.
The range function returns a list of numbers from zero to the given number minus one. It also has two- and three-argument forms (see the doc for more info):
range(n) == [0, 1, 2, ..., n - 1]
<< is the left-shift operator, and has the effect of multiplying the left hand side by two to the power of the right hand side:
x << n == x * 2**n
Thus the above range function (range(1, 1 << x)) returns [1, 2, 3, ..., 2**x - 1].
In the seconds usage of <<, the left-shift is being used as a bit-mask. It moves the 1-bit into the j-th bit, and performs a bit-wise and with i, so the result will be non-zero (and pass the if test) if and only if the j-th bit of i is set. For example:
j = 4
1 << j = 0b1000 (binary notation)
i = 41 = 0b101001
i & (1 << j) = 0b101001
& 0b001000
= 0b001000 (non-zero, the if-test passes)
i = 38 = 0b100110
i & (1 << j) = 0b100110
& 0b001000
= 0b000000 (zero, the if-test fails)
In short, x & (1 << y) is non-zero iff the y-th bit of x is set.
<< is the binary left shift operator. 1 << x is a way of saying two to the power of x.