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'
I wrote this bitwise Karatsuba multiplication algorithm. It does not use strings or math.pow. It's just divide-and-conquer-recursion, bitwise operations and addition:
def karatsuba(x,y):
n = max(x.bit_length(), y.bit_length())
if n < 2:
return x&y
# split in O(1)
n = (n + 1) >> 1
b = x >> n;
a = x - (b << n);
d = y >> n;
c = y - (d << n);
ac = karatsuba(a, c);
bd = karatsuba(b, d);
abcd = karatsuba(a+b, c+d);
return ac + ((abcd - ac - bd) << n) + (bd << (n << 1));
print(karatsuba(23,24))
print(karatsuba(-29,31))
# 552
# 381
It works absolutly fine with positive numbers, but obviously -29*31 is not equal 381.
What's the easiest way to fix the problem?
My first idea was to make the number positive with (~(-29)+1) = 29, store wheather it was negative or not in a boolean and handle that boolean in my return statement, but is there a better (maybe bitwise) solution?
Thanks in advance
The issue is with your exit case, in particular x&y returns the wrong value for negative numbers:
-1 & 1 == 1 # Needs to return -1
So you can fix this with testing for it or or just returning:
if n < 2:
return x*y
E.g.:
In []:
print(karatsuba(-29,31))
Out[]:
-899
You are given two 32-bit numbers, N and M, and two bit positions, i
and j. Write a method to set all bits between i and j in N equal to M
(e.g., M becomes a substring of N located at i and starting at j).
EXAMPLE: Input: N = 10000000000, M = 10101, i = 2, j = 6 Output: N =
10001010100
This problem is from Cracking the Coding interview. I was able to solve it using the following O(j - i) algorithm:
def set_bits(a, b, i, j):
if not b: return a
while i <= j:
if b & 1 == 1:
last_bit = (b & 1) << i
a |= last_bit
else:
set_bit = ~(1 << i)
a &= set_bit
b >>= 1
i += 1
return a
The author gave this O(1) algorithm as a solution:
def update_bits(n, m, i, j):
max = ~0 # All 1s
# 1s through position j, then zeroes
left = max - ((1 << j) - 1)
# 1s after position i
right = ((1 << i) - 1)
# 1’s, with 0s between i and j
mask = left | right
# Clear i through j, then put m in there
return (n & mask) | (m << i)
I noticed that for some test cases the author's algorithm seems to be outputting the wrong answer. For example for N = 488, M = 5, i = 2, j = 6 it outputs 468. When the output should be 404, as my O(j - i) algorithm does.
Question: Is there a way to get a constant time algorithm which works for all cases?
I think the author of the algorithm assumes the bound of j (six in your example) to be exclusive; this boils down to the question whether a range from 2 to 6 should include 6 (in Python that is not the case). In other words, if the algorithm is modified to:
def update_bits(n, m, i, j):
max = ~0 # All 1s
# 1s through position j, then zeroes
left = max - ((1 << (j+1)) - 1)
# 1s after position i
right = ((1 << i) - 1)
# 1’s, with 0s between i and j
mask = left | right
# Clear i through j, then put m in there
return (n & mask) | (m << i)
It works.
Nevertheless you can speed up things a bit as follows:
def update_bits(n, m, i, j):
# 1s through position j, then zeroes
left = (~0) << (j+1)
# 1s after position i
right = ((1 << i) - 1)
# 1’s, with 0s between i and j
mask = left | right
# Clear i through j, then put m in there
return (n & mask) | (m << i)
In this example, we simply shift the ones out of the register.
Note that you made an error in your own algorithm, in case b = 0, that does not mean you can simply return a, since for that range, the bits should be cleared. Say a = '0b1011001111101111' and b = '0b0' and i and j are 6 and 8 respectively, one expects the result to be '0b1011001000101111'. The algorithm thus should be:
def set_bits(a, b, i, j):
while i <= j:
if b & 1 == 1:
last_bit = (b & 1) << i
a |= last_bit
else:
set_bit = ~(1 << i)
a &= set_bit
b >>= 1
i += 1
return a
If I make this modification and I test the program with 10'000'000 random inputs, both algorithms always produce the same result:
for i in range(10000000):
m = randint(0,65536)
i = randint(0,15)
j = randint(i,16)
n = randint(0,2**(j-i))
if set_bits(m,n,i,j) != update_bits(m,n,i,j):
print((bin(m),bin(n),i,j,bin(set_bits(m,n,i,j)),bin(update_bits(m,n,i,j)))) #This line is never printed.
Of course this is not a proof both algorithms are equivalent (perhaps there is a tiny cornercase where they differ), but I'm quite confident that for valid input (i and j positive, i < j, etc.) both should always produce the same result.
I think there is one mistake in the proposed solution.
It should be:
def update_bits(n, m, i, j):
max = ~0 # All 1s
# 1s through position j + 1, then zeroes
left = max - ((1 << (j + 1)) - 1)
# 1s after position i
right = ((1 << i) - 1)
# 1’s, with 0s between i and j
mask = left | right
# Clear i through j, then put m in there
return (n & mask) | (m << i)
Because it said we should populate starting from j to i, so we need to clear bit j also. Result is 404 as expected.
To go a little bit further, in case m has more than (j - i + 1) bits, we need to change the return statement:
return (n & mask) | ((m << i) & ~mask)
create mask m which has set bits for all bits between <i,j>
you can use arithmetic bit shift left to create powers of 2 exploiting that powers of 2 minus one are numbers with all set bits up to the exponent-1
so set all bit <0,j> and then clear bits up to i-1
copy bits from M to N
so use m to clear bits in N and then copy the M bits instead of them. Do not forget to shift left M by i to match your case...
In C++ (sorry do not use python) is O(1) like this:
DWORD bitcopy(DWORD N,DWORD M,int i,int j)
{
DWORD m;
// set bits <0..j>
m =(2<<j)-1;
// clears <0..i)
if (i) m^=(2<<(i-1))-1;
// clear space for copied bits
N&=0xFFFFFFFF-m;
// copy bits M->N
N|=(M<<i)&m;
return N;
}
You can also use LUT for the i,j bits parts of m instead... as you got 32 bit numbers it needs just 32 or 64 numbers if you are not comfortable with the bit shifts...
This version seems to work well too, provided i <= j
def set_bits(n, m, i, j):
mask = (1 << (j + 1)) - (1 << i)
return n & ~mask | (m << i) & mask
Its Easy,You can implement it at your own once you've idea what you have to do...
heres 32 bit example:
given:
n = 10000000000000000000000000000000
m = 10101
i=2 , j=6
Step 1: Create Mask ->
int x=(~0); //All Ones 11111111111111111111111111111111
int left=(1<<i)-1; // 11
int right=x-((1<<j)-1); // 11111111111111111111111111000000
int mask=left | right; // 11111111111111111111111111000011
Step 2 : Clear bits between i and j in given number 'n' ->
int cleared = n & mask; // 10000000000000000000000000000000
Step 3 : Putting m in n between i and j (cleared bits) ->
int ans= cleared | m<<i; 10000000000000000000000001010100
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
Given a Python integer which is within the size of 4 bits, how does one transform it – with bitwise arithmetic instead of string processing – into an integer within the size of 4 bytes, for which each bit in the original corresponds to a byte which is the bit repeated 8 times?
For example: 0b1011 should become 0b11111111000000001111111111111111
With apologies to ncoghlan:
expanded_bits = [
0b00000000000000000000000000000000,
0b00000000000000000000000011111111,
0b00000000000000001111111100000000,
0b00000000000000001111111111111111,
0b00000000111111110000000000000000,
0b00000000111111110000000011111111,
0b00000000111111111111111100000000,
0b00000000111111111111111111111111,
0b11111111000000000000000000000000,
0b11111111000000000000000011111111,
0b11111111000000001111111100000000,
0b11111111000000001111111111111111,
0b11111111111111110000000000000000,
0b11111111111111110000000011111111,
0b11111111111111111111111100000000,
0b11111111111111111111111111111111,
]
Then just index this list with the nibble you want to transform:
>>> bin(expanded_bits[0b1011])
"0b11111111000000001111111111111111"
I'd just do a loop:
x = 0b1011
y = 0
for i in range(4):
if x & (1 << i):
y |= (255 << (i * 8))
print "%x" % y
The following recursive solution uses only addition, left/right shift operators and bitwise & operator with integers:
def xform_rec(n):
if n == 0:
return 0
else:
if 0 == n & 0b1:
return xform_rec(n >> 1) << 8
else:
return 0b11111111 + (xform_rec(n >> 1) << 8)
Or, as a one-liner:
def xform_rec(n):
return 0 if n == 0 else (0 if 0 == n & 0b1 else 0b11111111) + (xform_rec(n >> 1) << 8)
Examples:
>>> print bin(xform_rec(0b1011))
0b11111111000000001111111111111111
>>> print bin(xform_rec(0b0000))
0b0
>>> print bin(xform_rec(0b1111))
0b11111111111111111111111111111111)