Bitwise setting in C++ - c++

#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?

Related

Meaning of (n & 1 << b) in C++

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))

Logical & bitwise AND

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.

Check if C-style array equals other (compile-time) array

I've got a double[9] and want to check if it contains the values (1,0,0,0,1,0,0,0,1). Is there a cleaner way than this?
if (ornt1[0] == 1 && ornt1[1] == 0 && ornt1[2] == 0
&& ornt1[3] == 0 && ornt1[4] == 1 && ornt1[5] == 0
&& ornt1[6] == 0 && ornt1[7] == 0 && ornt1[8] == 1 )
I'm using C++.
It is not a good idea to compare double values strictly. I would recommend you create a constant array to compare against and then use a cycle and also use a tolerance(e.g. 1e-9):
bool doublesEqual(double a, double b) {
return fabs(a - b) < 1e-9;
}
const double expected[9] = {1,0,0,0,1, 0, 0, 0, 1};
bool equal = true;
for (int i = 0; i< 9; ++i) {
if (!doublesEqual(expected[i], ornt1[i])) {
equal = false;
break;
}
}
if (equal) { // do smth
EDIT: as suggested by John Zwinck I have edited the code to be able to handle the case when the array we compare contains only NAN. I have edited his suggestion a bit to make the code more readable. Please refer to his comment below for clarification why this is needed.

Is there a more elegant syntax for these boolean expressions?

I was just writing an improved linear version of a recursive Fibonacci algorithm, and realized that my boolean expressions look really bad and unreadable. Is there a cleaner way to do what I'm trying to do?
int fibonacci(int num) {
if (num <= 1)
return num;
// starts looking ugly here
int a = intExists(num-1);
int b = intExists(num-2);
bool aAndB = (a != -1 && b != -1);
bool justA = (a != -1 && b == -1);
bool justB = (a == -1 && b != -1);
int number = 0;
if (aAndB)
number = (a + b);
else if (justA)
number = (a + fibonacci(num - 2));
else if (justB)
number = (fibonacci(num-1) + b);
else
number = (fibonacci(num - 1) + fibonacci(num - 2));
map.push_back(Pair(num, number));
return number;
}
Thanks
If you're talking about:
bool aAndB = (a != -1 && b != -1);
then I would say, "no."
This code looks perfectly expressive to me. aAndB is initialized at the moment it comes in to being, and the conditions are very clear. This might look a bit odd when you're first starting out in C++, but before you know it it will be second nature and other constructs will seem silly.
One thing I would suggest is to make aAndB const if you don't intend to change it:
const bool aAndB = (a != -1 && b != -1);
This is even more expressive.
It also might give the compiler an additional opportunity to optimize your code.
Remember -- write code for humans to understand. Not for computers to understand.
Why don't you make a and b as bools and assign those as true if a == -1 and false otherwise. Then, the expressions will become easier to handle.
Could do a switch statement to clean up the if else statements a little. Other than that just add comments
You could rewrite it to use conditional branching, like this:
int fibonacci(int num) {
if (num <= 1)
return num;
int a = intExists(num-1);
int b = intExists(num-2);
const bool isA = (a != -1); // change in the definition
const bool isB = (b != -1); // change in the definition
int number = 0;
if (isA && isB)
number = (a + b);
else if (isA) // conditionnal branching
number = (a + fibonacci(num - 2));
else if (isB) // conditionnal branching
number = (fibonacci(num-1) + b);
else
number = (fibonacci(num - 1) + fibonacci(num - 2));
map.push_back(Pair(num, number));
return number;
}
I'm assuming that intExists(n) looks up map and if finds n in there, returns fibonacci(n) else it returns -1. Then you could do this:
int fibonacci(int num) {
if (num <= 1)
return num;
int a = intExists(num-1);
int b = intExists(num-2);
if (a == -1) // if a wasn't found, then compute it
a = fibonacci(num-1);
if (b == -1) // if b wasn't found, then compute it
b = fibonacci(num-2);
int number = a + b;
map.push_back(std::make_pair(num, number));
return number;
}
Bonus:
Here is another completely different implementation of fibonnacci() based on Binet's formula:
#include <cmath>
int fibonacci(int n) {
static const double e1 = 1.6180339887498948482045868343656; // = (1 + sqrt(5)) / 2
static const double e2 = -0.61803398874989484820458683436564; // = (1 - sqrt(5)) / 2
static const double c = 0.44721359549995793928183473374626; // = 1 / sqrt(5);
double f = c * (std::pow(e1, n) - std::pow(e2, n));
return static_cast<int>(f + 0.5);
}
int main() {
for (int n = 1; n < 15; ++n)
std::cout << fibonacci(n) << ' ';
}
It outputs:
1 1 2 3 5 8 13 21 34 55 89 144 233 377
Plain C++ code is clean enough:
bool a = intExists(num-1);
bool b = intExists(num-2);
if (a && b) {
//
} else if (a) {
//
} else if (b) {
//
} else {
//
}
int a = intExists(num-1);
int b = intExists(num-2);
bool aAndB = (a != -1 && b != -1);
bool justA = (a != -1 && b == -1);
bool justB = (a == -1 && b != -1);
Quick look into the approach you took. Under what circumstances can justB be true? (Hint: never)
That should help you simplify your approach, although there are better approaches than memoization.
Changing intExists to return boolean values, you can do a switch-case statements like that:
bool a = intExists(num-1);
bool b = intExists(num-2);
switch ((a << 1) + b) {
default: // none exists
case 1: // only b exist
case 2: // only a exist
case 3: // both exists
}
The rationale is to transform those booleans in a binary number
A slightly drastic rewrite is to let an external function handle the lookup table.
That way you don't need to care about more than one value at a time.
This one uses map so I didn't have to write so much in order to test it, but it should be easy enough to adapt:
std::map<int, int> table;
int fibonacci(int num);
int value(int num)
{
int result = table[num];
if (!result)
{
result = fibonacci(num);
table[num] = result;
}
return result;
}
int fibonacci(int num)
{
if (num <= 2)
return 1;
return value(num - 1) + value(num - 2);
}

Operator Overloading (int as bool)

I'm trying to write a code that returns 1s and 0s instead of true or false. But this doesn't seem to be right.
int Short_Vector::operator==(const Short_Vector& obj){
if(a == obj.a && b == obj.b && c == obj.c && d == obj.d){
return 1;
}else{
return 0;
}
}
So it should return a value for each variable.
I also tried this:
int Short_Vector::operator==(const Short_Vector& obj){
int a_tf, b_tf, c_tf, d_tf;
if(a == obj.a){
a_tf = 1;
}else{
a_tf = 0;
}
if(b == obj.b){
b_tf = 1;
}else{
b_tf = 0;
}
if(c == obj.c){
c_tf = 1;
}else{
c_tf = 0;
}
if(d == obj.d){
d_tf = 1;
}else{
d_tf = 0;
}
return(a_tf, b_tf, c_tf, d_tf)
}
But I got an error about the commas being an operator.
EDIT
Getting the error: error: conversion from 'int' to non-scalar type 'Short_Vector.
I'm trying to represent a vector that looks like this [9,1,5,5].
Then i'll say
`Short_Vector a(2, 6, 9, 4);
Short_Vector b(3, 8, 7, 6);
Short_Vector c = a == b;
cout<<c;`
Output is then: [0,0,0,0]
The second method can't work because the return type is an 'int' and '(a_tf, b_tf, c_tf, d_tf)' is not an int but 4 ints separated by commas.
Since you want to return 4 booleans you could do the following:
int Short_Vector::operator==(const Short_Vector& obj)
{
//...
return (a_tf) | (b_tf << 1) | (c_tf << 2) | (d_tf << 3);
}
//the caller would do the follwoing:
int result = (MyObject1 == MyObject2);
if(result & (1 << 1) //b_tf is set to 1;
{
}
if(result & (1 << 3) //d_tf is set to 1;
{
}
You can use std::bitset to set a bit for equality of each member
std::bitset<4> Short_Vector::operator==(const Short_Vector& obj){
std::bitset<4> r;
r[0] = (a == obj.a);
r[1] = (b == obj.b);
r[2] = (c == obj.c);
r[3] = (d == obj.d);
return r;
}
And you can use it like
Short_Vector a(1,2,3,4);
Short_Vector b(1,0,3,4);
std::bitset<4> res = (a==b);
std::cout << res;
Should give you
1011
std::bitset is good because it provides convenient methods like all any and none (and many more). So that you can check aggregate values with ease.
If you want to have the result as a Short_Vector, try this:
Short_Vector Short_Vector::operator==(const Short_Vector& obj) {
return Short_Vector(
a == obj.a,
b == obj.b,
c == obj.c,
d == obj.d
);
}
The comma operator won't work the way you presumed. It will actually evaluate each of its operands and return the last. The compiler gave you a warning about this little misconception.
One alternative is to set each bit containing the numeric true/false equivalent of your boolean expressions:
unsigned int n = 0;
n |= (a == obj.a) << 0;
n |= (b == obj.b) << 1;
n |= (c == obj.c) << 2;
n |= (d == obj.d) << 3;
return n;
You can use a smaller datatype like char or you can use std::bitset.
If you must use an int as a return type, you could use the left shift operator and do something like:
int result = 0;
result += a_tf << 3; //Shifts the bit 3 places to the left.
result += b_tf << 2; //Shifts the bit 2 places to the left.
result += c_tf << 1; //Shifts the bit 1 place to the left.
result += d_tf; //Puts d_tf as bit 0
return result;
And to get each one back out use the bit-wise and:
result = obj1 == obj2; //Where obj1 and 2 are your compared objects
int a_tf = (result >> 3) & 1;
int b_tf = (result >> 2) & 1;
int c_tf = (result >> 1) & 1;
int d_tf = result & 1;
Though I have to say Named's solution using a bitset is more easily understood, and inserting/retrieving a single value is much easier that way.