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))
Related
I am trying to solve the following task. Given an integer x, I want to compute 2 numbers (a and b) which are:
1) divisible by 2 or 3 (e.g a % 2 == 0 or a % 3 == 0 )
2) x = a +
b
I wrote the following code, to find such a and b.
cin >> x;
if (x % 2 == 0) {
a = b = x / 2;
} else {
a = x / 2;
b = a + 1;
}
while((a % 3 !=0 || a % 2 != 0) && (b % 2 != 0 || b % 3 != 0)) {
a++;
b--;
}
However it does not work. For example when x is 13, it prints out that a = 6 and b = 7. But 7 is not divisible by 2 or 3. What is the problem ?
Examine your continuation condition carefully (where n is some arbitrary integer, possibly different in each use so, for example a != 3n simply means that a is not a multiple of three). I'll show the process:
while((a % 3 != 0 || a % 2 != 0) && (b % 2 != 0 || b % 3 != 0))
( a != 3n OR a != 2n ) AND ( b != 2n OR b != 3n )
( a != 6n ) AND ( b != 6n )
It says: continue while both a is not a multiple of both two and three, and b is not a multiple of both two and three. In other words, it will only continue if both a and b are multiples of six. On the flip side of that, it will of course exit if either a or b is not a multiple of six.
Since an input value of 13 sets a = 6 and b = 7, the continuation case is false on the first iteration (seven is not a multiple of six).
Perhaps it would be better to rethink the way you figure out whether certain number combinations are valid(a). For example (assuming the numbers have to be between 1 and N - 1 since, otherwise, your solution space is likely to be infinite), you could use something like:
#include <iostream>
int main() {
// Get the number.
int num;
std::cout << "Number? ";
std::cin >> num;
// Check all i + j = n for 1 <= i,j < n.
for (int i = 1, j = num - 1; i < j; ++i, --j) {
// Disregard if either number not a multiple of 2 or 3.
if ((i % 2) != 0 && (i % 3) != 0) continue;
if ((j % 2) != 0 && (j % 3) != 0) continue;
std::cout << num << " => " << i << ", " << j << "\n";
return 0;
}
std::cout << num << " => no solution\n";
return 0;
}
Note my use of i < j is the for continuation condition, this is assuming they have to be distinct numbers. If they're allowed to be the same number, change that to i <= j.
(a) Using all of and, or, and not (even implicitly, by the reversal of continuation and exit conditions), is sometimes more trouble than it's worth since De Morgan's theorems tend to come into play:
_____ _ _
A ∩ B ⇔ A ∪ B : (not(A and B)) is ((not A) or (not B))
_____ _ _
A ∪ B ⇔ A ∩ B : (not(A or B)) is ((not A) and (not B))
In cases like that, code can become more readable if you break out the individual checks.
Interestingly, if you run that code with quite a few input values, you'll see the pattern that, if a solution exists, one of the numbers in that solution is always two or three.
That's because, other than the pathological cases of sums less than five (or less than four if the solution is allowed to have identical numbers):
every even number 2n, n > 1 is the sum of 2 and 2n - 2, both multiples of two (2n - 2 = 2(n - 1)); and
every odd number 2n + 1, n > 2 is the sum of 3 and 2n + 1 - 3, the first a multiple of three and the second a multiple of two (2n + 1 - 3 = 2n - 2 = 2(n - 1)).
So, in reality, no loop is required:
if (num < 5) { // 4 if allowing duplicates.
std::cout << num << " => no solution\n";
} else {
int first = (num % 2) == 0 ? 2 : 3;
std::cout << num << " => " << first << ", " << (num - first) << "\n";
}
This actually gives a different result for some numbers, such as 17 = 2 + 15 = 3 + 14 but both solutions are still correct.
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).
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.
std::cout << (abs(b - c) < a) && a < b + c ? 1 : 0;
I want to check if given values can create triangle. I got warnings:
second operand of conditional expression has no effect [-Wunused-value]
third operand of conditional expression has no effect [-Wunused-value]
What's wrong?
Your code translates to:
((std::cout << (abs(b - c) < a)) && a < b + c) ? 1 : 0;
Firstly, operator<< has higher operator precedence than operator&&.
Only the value of abs(b - c) < a will be printed and the (a < b + c ? 1 : 0) part will be AND-ed together with the return value of std::ostream::operator bool.
But the warning is about 1 and 0 not being assigned to anything nor having any side effects, because && precedes the ternary conditional (?:).
The correct code is either:
std::cout << (abs(b - c) < a && a < b + c ? 1 : 0);
// same as std::cout << ((abs(b - c) < a && a < b + c) ? 1 : 0);
or
std::cout << (abs(b - c) < a && (a < b + c ? 1 : 0));
In fact, they're equivalent (apart that one calls operator<< with bool and the other with int), no ternary operator needed:
std::cout << (abs(b - c) < a && a < b + c);
This question already has answers here:
Mathematically Find Max Value without Conditional Comparison
(18 answers)
Closed 9 years ago.
So i have too get two numbers from user input, and find the max of the two numbers without using if statements.
The class is a beginner class, and we have too use what we already know. I kinda worked something out, but it only works if the numbers are inputted with the max number first.
#include <iostream>
using namespace std;
int main()
{
int x = 0, y = 0, max = 0;
int smallest, largest;
cout << "Please enter 2 integer numbers, and i will show you which one is larger: ";
cin >> x >> y;
smallest = (x < y == 1) + (x - 1);
smallest = (y < x == 1) + (y - 1);
largest = (x < y == 1) + (y - 1);
largest = (y > x == 1) + (x + 1 - 1);
cout << "Smallest: " << smallest << endl;
cout << "Largest: " << largest << endl;
return 0;
}
Thats what i have so far, but after putting different test data in, i found out it only works for numbers such as 4,5 or 6,7. But numbers with more then 2 spaces between eachother they dont such as, 4,8 or 5, 7. Any help would be appreciated.
I saw this question in Cracking the Coding interview book.
Let’s try to solve this by “re-wording” the problem We will re-word the problem until we get something that has removed all if statements
Rewording 1: If a > b, return a; else, return b
Rewording 2: If (a - b) is negative, return b; else, return a
Rewording 3: If (a - b) is negative, let k = 1; else, let k = 0 Return a - k * (a - b)
Rewording 4: Let c = a - b Let k = the most significant bit of c Return a - k * c
int getMax(int a, int b) {
int c = a - b;
int k = (c >> ((sizeof(int) * CHAR_BIT) - 1)) & 0x1;
int max = a - k * c;
return max;
}
Source: http://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/098478280X
Edit: This code works even when a-b overflows.
Let k equal the sign of a-b such that if a-b >=0, then k is 1, else k=0.Let q be the inverse of k. Above code overflows when a is positive or b is negative, or the other way around. If a and b have different signs, then we want the k to equal sign(a).
/* Flips 1 to 0 and vice-versa */
public static int flip(int bit){
return 1^bit;
}
/* returns 1 if a is positive, and 0 if a is negative */
public static int sign(int a){
return flip((a >> ((sizeof(int) * CHAR_BIT) - 1)) & 0x1);
}
public static int getMax(int a, int b){
int c = a - b;
int sa = sign(a-b); // if a>=0, then 1 else 0
int sb = sign(a-b); // if b>=1, then 1 else 0
int sc = sign(c); // depends on whether or not a-b overflows
/* If a and b have different signs, then k = sign(a) */
int use_sign_of_a = sa ^ sb;
/* If a and b have the same sign, then k = sign(a - b) */
int use_sign_of_c = flip(sa ^ sb);
int k = use_sign_of_a * sa + use_sign_of_c * sc;
int q = flip(k); //opposite of k
return a * k + b * q;
}
Here is a funny solution:
int max_num = (x>y)*x + (y>=x)*y;
Assuming that you have covered bitwise operators already you can do this:
max = a-((a-b)&((a-b)>>(sizeof(int)*8-1)));
This is based off of the solution from Mathematically Find Max Value without Conditional Comparison that #user93353 pointed out in the comments above.
This may be overkill if you really are just trying to avoid if statements, not comparisons in general.
You can try this code to find max and min for two input variables.
((a > b) && (max = a)) || (max=b);
((a < b) && (min = a)) || (min=b);
For three input variables you can use similar method like this:
int main()
{
int a = 10, b = 9 , c = 8;
cin >> a >> b >> c;
int max = a, min = a;
// For Max
((a > b) && (a > c) && (max=a)) ||
((b > c) && (b > a) && (max=b)) ||
(max=c) ;
// For min
((a < b) && (a < c) && (min=a)) ||
((b < c) && (b < a) && (min=b)) ||
(min=c) ;
cout << "max = " << max;
cout << "and min = " << min;
return 1;
}
One run is:
:~$ ./a.out
1
2
3
max = 3 and min = 1
Edit
Thanks to #Tony D: This code will fail for negative numbers.
One may try this for negative numbers for two inputs to find max(not sure for this):
((a > b) && ( a > 0 && (max = a))) || ((b > a) && (max = b)) || (max = a);