Is there any clever way to mix two bit sequences in such way that bits from first sequence will be on odd places, and bits from second sequence will be on even places.
Both sequences are no longer than 16b so output will fit into 32bit integer.
Example:
First sequence : 1 0 0 1 0 0
Second sequence : 1 1 1 0 1 1
Output : 1 1 0 1 0 1 1 0 0 1 0 1
I thought about making integer array of size 2^16 and then the output would be:
arr[first] << 1 | arr[second]
Have a look at http://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup This page lists the obvious (for loop) and 3 optimized algorithms. Neither one is particularly simple but without testing I'd guess they are considerably faster than a loop.
in C#:
public Int32 Mix(Int16 b1, Int16 b2)
{
Int32 res = 0;
for (int i=0; i<16; i++)
{
res |= ((b2 >> i) & 1) << 2*i;
res |= ((b1 >> i) & 1) << 2*i + 1;
}
return res;
}
Related
This statement checks whether a number is 32 bits.
0 < res <= (1 << 31) -1
I can't seem to understand how, can someone help understand this bit shift syntax?
Well, lets begin with an example:
1 in binary is 1
2 in binary is 10
4 in binary is 100
We can see that we need to 'add' an 0 at the end of each number to multiply by 2 and in most language we can do this with this syntax: number << 1
Here we are saying that we add a 1 time a 0 to the left. number >> 1 and here we add 1 time a 0 to the right.
So 1 << 31 means 1 * 2 * 2 * 2 ... 31 times which means 2^31 (so 32 bits)
I have a 2 bit number x stored in a single byte, and I would like to invert it, so that 0 is transformed to 3, 1 to 2, 2 to 1 and 3 to 0.
Isx^3be the correct way of doing this?
Also, for arbitrary N bit number x, will x^((1<<N)-1) be correct ?
x^3 is good for two bit numbers. If you have 4 bit numbers, use x ^ 15, or write it in hex, x ^ 0x0f if you want.
No, x^(N-1) will not work. What will work is x^(pow(2,N)-1)
Code :
((~x)&(0x3))
Test Code (Same piece of code should work in C++ too):
public static void main(String[] args) {
// TODO Auto-generated method stub
//System.out.println("Hello");
for(int i=0; i<=3; i++) {
System.out.println("Complement of " + i + " is " + (~i & 0x3));
}
}
Result:
Complement of 0 is 3
Complement of 1 is 2
Complement of 2 is 1
Complement of 3 is 0
I have been stuck with this problem for two days and I still can't get it right.
Basically, I have a 2D array with relations between certain numbers (in given range):
0 = the order doesn't matter
1 = the first number (number in left column) should be first
2 = the second number (number in upper row) should be first
So, I have some 2D array, for example this:
0 1 2 3 4 5 6
0 0 0 1 0 0 0 2
1 0 0 2 0 0 0 0
2 2 1 0 0 1 0 0
3 0 0 0 0 0 0 0
4 0 0 2 0 0 0 0
5 0 0 0 0 0 0 0
6 1 0 0 0 0 0 0
And my goal is to create a new array of given numbers (0 - 6) in such a way that it is following the rules from the 2D array (e.g. 0 is before 2 but it is after 6). I probably also have to check if such array exists and then create the array. And get something like this:
6 0 2 1 4 5
My Code
(It doesn't really matter, but I prefer c++)
So far I tried to start with ordered array 0123456 and then swap elements according to the table (but that obviously can't work). I also tried inserting the number in front of the other number according to the table, but it doesn't seem to work either.
// My code example
// I have:
// relArr[n][n] - array of relations
// resArr = {1, 2, ... , n} - result array
for (int i = 0; i < n; i++) {
for (int x = 0; x < n; x++) {
if (relArr[i][x] == 1) {
// Finding indexes of first (i) and second (x) number
int iI = 0;
int iX = 0;
while (resArr[iX] != x)
iX++;
while (resArr[iI] != i)
iI++;
// Placing the (i) before (x) and shifting array
int tmp, insert = iX+1;
if (iX < iI) {
tmp = resArr[iX];
resArr[iX] = resArr[iI];
while (insert < iI+1) {
int tt = resArr[insert];
resArr[insert] = tmp;
tmp = tt;
insert++;
}
}
} else if (relArr[i][x] == 2) {
int iI = 0;
int iX = 0;
while (resArr[iX] != x)
iX++;
while (resArr[iI] != i)
iI++;
int tmp, insert = iX-1;
if (iX > iI) {
tmp = resArr[iX];
resArr[iX] = resArr[iI];
while (insert > iI-1) {
int tt = resArr[insert];
resArr[insert] = tmp;
tmp = tt;
insert--;
}
}
}
}
}
I probably miss correct way how to check whether or not it is possible to create the array. Feel free to use vectors if you prefer them.
Thanks in advance for your help.
You seem to be re-ordering the output at the same time as you're reading the input. I think you should parse the input into a set of rules, process the rules a bit, then re-order the output at the end.
What are the constraints of the problem? If the input says that 0 goes before 1:
| 0 1
--+----
0 | 1
1 |
does it also guarantee that it will say that 1 comes after 0?
| 0 1
--+----
0 |
1 | 2
If so you can forget about the 2s and look only at the 1s:
| 0 1 2 3 4 5 6
--+--------------
0 | 1
1 |
2 | 1 1
3 |
4 |
5 |
6 | 1
From reading the input I would store a list of rules. I'd use std::vector<std::pair<int,int>> for this. It has the nice feature that yourPair.first comes before yourPair.second :)
0 before 2
2 before 1
2 before 4
6 before 0
You can discard any rules where the second value is never the first value of a different rule.
0 before 2
6 before 0
This list would then need to be sorted so that "... before x" and "x before ..." are guaranteed to be in that order.
6 before 0
0 before 2
Then move 6, 0, and 2 to the front of the list 0123456, giving you 6021345.
Does that help?
Thanks for the suggestion.
As suggested, only ones 1 are important in 2D array. I used them to create vector of directed edges and then I implemented Topological Sort. I decide to use this Topological Sorting Algorithm. It is basically Topological Sort, but it also checks for the cycle.
This successfully solved my problem.
I'm writing a program that exchanges the values of the bits on positions 3, 4 and 5 with bits on positions 24, 25 and 26 of a given 32-bit unsigned integer.
So lets say I use the number 15 and I want to turn the 4th bit into a 0, I'd use...
int number = 15
int newnumber = number & (~(1 << 3));
// output is 7
This makes sense because I'm exchanging the 4th bit from 1 to 0 so 15(1111) becomes 7(0111).
However this wont work the other way round (change a 0 to a 1), Now I know how to achieve exchanging a 0 to a 1 via a different method, but I really want to understand the code in this method.
So why wont it work?
The truth table for x AND y is:
x y Output
-----------
0 0 0
0 1 0
1 0 0
1 1 1
In other words, the output/result will only be 1 if both inputs are 1, which means that you cannot change a bit from 0 to 1 through a bitwise AND. Use a bitwise OR for that (e.g. int newnumber = number | (1 << 3);)
To summarize:
Use & ~(1 << n) to clear bit n.
Use | (1 << n) to set bit n.
To set the fourth bit to 0, you AND it with ~(1 << 3) which is the negation of 1000, or 0111.
By the same reasoning, you can set it to 1 by ORing with 1000.
To toggle it, XOR with 1000.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
How do you set, clear and toggle a single bit in C?
Removing lowest order bit
n is a positive integer. How can its rightmost set bit be unset?
Say n= 7 => n = 0111.
I want 0110 as the output. Is there any simple bitwise hack to achieve the goal?
Try n & (n-1) where & is bitwise AND
n = 7
n - 1 =6
n & (n-1)=> 0 1 1 1 (7)
& 0 1 1 0 (6)
---------
0 1 1 0 (done!)
EDIT (in response to the comment given by Forest)
n = 6
n - 1 = 5
n & (n-1)=> 0 1 1 0 (6)
& 0 1 0 1 (5)
---------
0 1 0 0 (done!)
Your question is unclear.
If you just want to unset bit 0, here are some methods (with slight variations in behavior depending on your types involved):
x &= -2;
x &= ~1;
x -= (x&1);
If you want to unset the lowest bit among the bits that are set, here are some ways:
x &= x-1;
x -= (x&-x);
Note that x&-x is equal to the lowest bit of x, at least when x is unsigned or twos complement. If you want to do any bit arithmetic like this, you should use only unsigned types, since signed types have implementation-defined behavior under bitwise operations.
unsigned int clr_rm_set_bit(unsigned int n)
{
unsigned int mask = 1;
while(n & mask) {
mask <<= 1;
}
return n & ~mask;
}