I am using bitwise operators to store some boolean values in a variable. I assume i'm storing them appropiately, although here are my assignments:
int bit = 0;
bit |= 1;
bit |= 2;
bit |= 4;
bit |= 8;
What i am unsure of is the checking part. I have a simple knowledge about the difference between logical and bitwise operators. Here's how i check the values:
if ((bit & 1) && (bit & 2) && (bit & 8)) {
std::cout << "a" << std::endl;
}
else {
std::cout << "b" << std::endl;
}
I want to know if that kind of conditional is correct (i've done some tests, but i might be missing something) and also i want to know if i can check multiple bits at the same time, for example:
if (bit && (1 & 2 & 8) {
std::cout << "a" << std::endl;
}
else {
std::cout << "b" << std::endl;
}
I know that the last won't work as desired (at least that's what tests gave me), but i wanted to illustrate my idea.
i want to know if i can check multiple bits at the same time
Yes, you can do that but your code is not correct.
1 & 2 & 8 will always be zero. You need to use 1 | 2 | 8.
bit && (1 & 2 & 8) is not correct because of the above.
You can use:
if ( (bit & (1 | 2 | 8)) == (1 | 2 | 8) ) {
std::cout << "a" << std::endl;
}
else {
std::cout << "b" << std::endl;
}
The expression (bit & 1) && (bit & 2) && (bit & 8) is logically the same as the expression (bit & (1 | 2 | 8)) == (1 | 2 | 8)
See it working at https://ideone.com/KdGjiO.
The bitwise AND operator compares each bit of the first operand to the
corresponding bit of the second operand. If both bits are 1, the
corresponding result bit is set to 1. Otherwise, the corresponding
result bit is set to 0.
Since the AND operation if you want to check n. bit of the value you must AND it with 2^(n-1). If the bit is set the result of the bitwise operation will be greater than zero that means value is logically true otherwise it will be zero (or logically false)
if ((bit & 1) && (bit & 2) && (bit & 8))
this expression is suits what you want to do
if (bit && (1 & 2 & 8))
but 1 & 2 & 8 will produce always zero. The correct expression is:
if ((bit & (1 | 2 | 8)) == (1 | 2 | 8))
You could use a binary literal to compare:
#include <iostream>
int main() {
int bit = 0;
bit |= 1;
bit |= 2;
bit |= 4;
bit |= 8;
if ((bit & 0b1111) == 0b1111) {
std::cout << "YES!";
}
return 0;
}
Or as a function:
bool compareIntBool(const int bit, const int compareTo) {
return (bit & compareTo) == compareTo ? true : false;
}
Then call it with a binary literal:
if (compareIntBool(bit, 0b1111)) {
std::cout << "YES";
}
Difference between both are simple
&&-First statement is false means it cannot check second value
&-It is check both the value either the first value is true or false
Here's an alternative implementation of your first example:
static const char * const table[] = {
"a", "a", "a", "a",
"a", "a", "a", "a",
"a", "a", "a", "b",
"a", "a", "a", "b",
};
std::cout << table[bit] << std::endl;
Of course, it might be safer to do the lookup as table[bit&0xF] instead.
Related
This question already has answers here:
Fastest way to produce a mask with n ones starting at position i
(5 answers)
Closed 3 years ago.
I'm learning bit manipulation and bitwise operators currently and was working on a practice problem where you have to merge a subsection[i,j] of an int M into N at [i,j]. I created the mask in a linear fashion but after googling i found that ~0 << j | ((1 << i) - 1) creates the mask I wanted. However, I am not sure why. If anyone could provide clarification that would great, thanks.
void merge(int N, int M, int i, int j){
int mask = ~0 << j | ((1 << i) - 1);
N = N & mask; // clearing the bits [i,j] in N
mask = ~(mask); // inverting the mask so that we can isolate [i,j] in
//M
M = M & mask; // clearing the bits in M outside of [i,j]
// merging the subsection [i,j] in M into N at [i,j] by using OR
N = N | M;
}
~0 is the "all 1 bits" number. When you shift it up by j, you make the least significant j bits into 0:
1111111111111111 == ~0 == ~0 << 0
1111111111111110 == ~0 << 1
1111111111100000 == ~0 << 5
1111111110000000 == ~0 << 7
1 << i is just the i + 1th least significant bit turned on.
0000000000000001 == 1 << 0
0000000000000010 == 1 << 1
0000000000001000 == 1 << 3
0000000001000000 == 1 << 6
When you subtract 1 from this, there is a one carried all the way from the left, so you are left with all the bits before the 1 bit becoming 1 (So you end up with the first i least significant bits turned on).
0000000000000000 == (1 << 0) - 1
0000000000000001 == (1 << 1) - 1
0000000000000111 == (1 << 3) - 1
0000000000111111 == (1 << 6) - 1
When you or them, you end up with a window between the jth least significant bit and the i + 1th least significant bit turned on (inclusive).
1111111110000000 == ~0 << 7
0000000000000111 == (1 << 3) - 1
1111111110000111 == ~0 << 7 | ((1 << 3) - 1)
7 3
When you & a number with this mask, you clear the bits in the range (i, j] (The ith bit itself is not included).
When you ~ the mask, you get a new mask that will only give you the bits in the range (i, j].
1111111110000111 == ~0 << 7 | ((1 << 3) - 1)
0000000001111000 == ~(~0 << 7 | ((1 << 3) - 1))
Which could also be constructed with something like ((1 << j) - 1) & ~((1 << i) - 1).
While referring a C++ code written by someone else in CodeChef for a particular problem I found a new way(at least for me) of writing a conditional statement like this: if (n & 1 << b).
The entire code snippet(a function) is as follows:
int Solve(int tim, int n)
{
if (tim < 0)
return 1;
int res = 0;
for (int b = Maxb - 1; b >= 0; b--)
if (n & 1 << b)
{
int my = b - __builtin_popcount(tim & ((1 << b) - 1));
res += 1 << my;
if (tim & 1 << b)
return res;
}
res++;
return res;
}
I know the bitwise AND operation and also a left shift operation means when we use separately. However, here the combination of both in a conditional statement made me confuse to read the logic. When I searched for the references, I couldn't find a situation where both operations come up together. Therefore, can anybody tell me the meaning or what exactly going on here?
It's a check to see if the bit at position 'b' in the binary representation of n is turned on or off.
if (n & 1 << b)
is essentially
if (n & (1 << b))
because of operator precedence.
these are the values that 1 << b gets (righthand side is in binary):
For b == 0, (1 << b) == ...000000001
For b == 1, (1 << b) == ...000000010
For b == 2, (1 << b) == ...000000100
For b == 3, (1 << b) == ...000000100
For b == 3, (1 << b) == ...000001000
For b == 4, (1 << b) == ...000010000
and so on.
When you & the value 1 << b with n you essentially turn off all of n's bits except for the bit in the location corresponding to the 1 in the binary representation of 1 << b.
This means that you would only get a non-zero result for n & (1 << b) if the bit of n that was in the location corresponding to the 1 bit of (1 << b) was turned on. If it wasn't, all of the bits would turn off and since it was already 0, it would stay 0 and the end result would be 0.
The if statement receives this final result, if it's positive (the bit was on) it will enter the if, otherwise (if the bit was off), the end result would be 0 and the if statement would consider the statement n & (1 << b) to be false.
Per http://en.cppreference.com/w/cpp/language/operator_precedence
<< takes precedence over &. So, like #Ryan's comment, (n & 1 << b) is equivalent to (n & (1 << b))
So basically
int num = rand(2); //random number from 0-2
int otherNum, otherOtherNum;
otherNum = implement this
otherOtherNum = implement this
For example, if num is 2, otherNum and otherOtherNum must be set to 0 and 1 (or 1 and 0).
How would you implement this? Assume you can't use branching or look up tables. Yes i'd like a bit manipulation solution. Yes i'd like the solution to be faster than a solution that uses modulus operator (as this is essentialy a division).
I think a lookup might be the fastest but not sure, I dont like that solution though.
You can also do this with XOR and bit masking.
#include <stdio.h>
void
f(unsigned val, unsigned ary[3])
{
ary[0] = val;
ary[1] = (ary[0] ^ 1) & 1;
ary[2] = (ary[0] ^ 2) & 2;
}
int
main()
{
unsigned ary[3] = {0};
f(0, ary);
printf("f(0) = %d %d %d\n", ary[0], ary[1], ary[2]);
f(1, ary);
printf("f(1) = %d %d %d\n", ary[0], ary[1], ary[2]);
f(2, ary);
printf("f(2) = %d %d %d\n", ary[0], ary[1], ary[2]);
return 0;
}
This will print:
f(0) = 0 1 2
f(1) = 1 0 2
f(2) = 2 1 0
otherNum = (num + 1) % 3
otherOtherNum = (num + 2) % 3
You could use an in-register lookup table, if the restriction on look-up tables means avoiding memory access. The in-register lookup-table is simply a compile-time constant.
const int tab = ((1 << 0) | (2 << 4) |
(0 << 8) | (2 << 12) |
(0 << 16) | (1 << 20));
int num = rand(2); //random number from 0-2
int otherNum, otherOtherNum;
otherNum = (tab >> num*8) & 0xf;
otherOtherNum = (tab >> (num*8+4)) & 0xf;
My 2 pee.
int main()
{
std::srand(std::time(0));
int num = std::rand() % 3; //random number from 0-2
int otherNum = (0b001001 >> (num << 1)) & 0b11;
int otherOtherNum = (0b010010 >> (num << 1)) & 0b11;
std::cout << num << '\n';
std::cout << otherNum << '\n';
std::cout << otherOtherNum << '\n';
}
NOTES:
0b001001 = 9
0b010010 = 18
0b11 = 3
This method basically uses a table stored in the bits of an integer and shifts the relevant bits into the desired variavle.
Another option would be to use an array for lookup, this avoids any additions and modulus although I'm not convinced it's faster at all:
int lookup[3] = {1, 2, 0};
int num = rand(2); //random number from 0-2
int otherNum, otherOtherNum;
otherNum = lookup[num];
otherOtherNum = lookup[otherNum]
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
A girl writes N numbers on the board (odd and even numbers) and then, she modifies only even numbers and inverts its binary representation (from the left to the right ) and replaces each even number. Write a code for the same.
0 <= n <= 10^7
I made a code for this, where my partial code looks like this:
int a[100000];
while ( t != 0 ) // t is the number in which input is taken
{
k = t & 1;
if ( k == 1 )
a[i] = 0; // a is the array in which bits of new number will be stored
else
a[i] = 1;
i++;
t = t >> 1;
}
for ( j = i; j >= 0; j-- )
{
if (a[j] == 1)
{
num = num + pow(2,j)*a[j]; // num is the number to be formed
}
}
cout<<num<<"\n";
But my answer comes out to be wrong for some values, for example for 8, it outputs 7. What is wrong with this? Thanks!
Problem link:
http://www.spoj.com/problems/EC_CONB/
Edit: ( In response to Pete's answer )
while ( t != 0 )
{
k = t & 1;
if ( k == 1 )
a[i] = 0;
else
{
a[i] = 1;
num = num + pow(2,i);
}
i++;
t = t >> 1;
}
cout<<num<<"\n";
}
This still shows the same problem, outputs the value of 8 as 7.
The problem actually wants you to reverse the bits not invert them. So the part where you check if k == 1, and putting 0 instead is not correct, because that inverts the bits.
What you need to do is reverse the ordering of the bits as follows:
1000 (8) -> 0001 (1)
1010 (10) -> 0101 (5)
Sample code based on your code:
while (t != 0)
{
k = t & 1;
// push the output array to the left
num <<= 1;
// add the read bit to the beginning of the output array
num += k;
t = t >> 1;
}
Explanation:
The basic idea is that we read bits from the input number one-by-one, and push them to the beginning of the output number.
Below is a trace of reversing a number (1011) at each iteration:
iterations 0 1 2 3 4
input 1011 101 10 1 0
output 0 1 11 110 1101
You appear to be reading a[i] after incrementing i, so the behaviour is undefined.
Instead of creating an array, accumulate the result in the first loop.
Arrays? Loops? Not necessary.
Reversing the number like that is equivalent to completely reversing the integer and then right-justifying it, like this (not tested)
// reverse from http://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel
// swap odd and even bits
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
// swap consecutive pairs
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
// swap nibbles ...
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
// swap bytes
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
// swap 2-byte long pairs
v = ( v >> 16 ) | ( v << 16);
// right-justify
v /= v & -v;
v should be an uint32_t.
#define OUTGOING_MASK 0x0c
#define OUTGOING_DISABLED 0x04
#define OUTGOING_ENABLED 0x08
#define OUTGOING_AUTO 0x00
#define REFER_SUPPORTED 0x80
Assume support is some value of type int.
I have a getter function
int get()
{
if(OUTGOING_DISABLED == support & OUTGOING_MASK)
return 1;
else if(OUTGOING_ENABLED == support & OUTGOING_MASK)
return 2;
else if(OUTGOING_AUTO == support & OUTGOING_MASK)
return 3;
}
I need to write set function for this like
void set(int val)
{
if(val ==1)
//todo
else if(value == 2)
//todo
else if(value == 3)
//todo
}
How to write getter and setter functions for this?
I need to get/set the support variable here
REFER_SUPPORTED will always be set in support.
I have a statement such as a1 = b & a2; How to know the value of b using bitwise operators?
You can't recover value of b, unless a has ALL bits set. "&" is irreversible.
Explanation. & operation has following table:
a b result
1 & 1 = 1
0 & 1 = 0
1 & 0 = 0
0 & 0 = 0
which means, to recover b, you could try to use following table:
a result b
0 0 unknown - could be 1 or 0
0 1 invalid/impossible - could not happen
1 0 0
1 1 1
As you can see it isn't possible to guess b in all cases.
In expression a & b = c, if you know c and a, you can't recover b, because for every zeroed bit of c, and if corresponding bit of a is also zero, there are two possible states of corresponding bits of b. You can reliably recover b only if every bit of a is set to 1.
You don't. In general, you can't recover that info given only a1 and a2. To see this, consider the case of a2 == 0. b & 0 is always 0.
Is the following what you want:
void set(int val)
{
support &= ~OUTGOING_MASK;
support |= REFER_SUPPORTED;
if(val == 1)
{
support |= OUTGOING_DISABLED;
}
else if(value == 2)
{
support |= OUTGOING_ENABLED;
}
else if(value == 3)
{
support |= OUTGOING_AUTO;
}
}
If that is the case, then I believe you getter function is also wrong. According to my understanding, it should be as follows:
int get()
{
if(OUTGOING_DISABLED == ((support & OUTGOING_MASK) >> 2))
return 1;
else if(OUTGOING_ENABLED == ((support & OUTGOING_MASK) >> 2))
return 2;
else if(OUTGOING_AUTO == ((support & OUTGOING_MASK) >> 2))
return 3;
}
You could use the following code to print out the binary equivalent
void printBit(int n)
{
unsigned int i;
i = 1<<(sizeof(n) * 8 - 1);
while (i > 0)
{
if (n & i)
{
printf("1");
}
else
{
printf("0");
}
i >>= 1;
}
}
That would simply print out the binary equivalent of 'b'. Is that what you want to do?