This question already has answers here:
Can I use bitwise operators instead of logical ones?
(5 answers)
Closed 6 years ago.
1st Semester Student here. I'm confused about the differences between the bitand (&) and the logical and (&&), and the same with the bitor (|), the logical or (||), and the Xor (^). Specifically, I've a bit of code that I thought required the || or && to function, but.. apparently not? Here's the code in question:
cout << "Please enter your biological sex (M or F): " << endl;
cin >> sex;
//Repetition Structure
while (toupper(sex) != 'M' && 'F')
{
cout << "Invalid entry. Please enter your biological sex (M or F): " << endl;
cin >> sex;
} //end while
I tried using || at first, but it gave me the "invalid entry" reply no matter how I answered it. I looked around on the forums, found that && would be better and tried using it. It worked - at first. Then, for no apparent reason, it stopped taking 'F' as an answer (the code wasn't changed).
To correct this, I tried using Xor (^) which failed, and then bitand (&, instead of &&), which apparently made it function correctly once more. But, I've seen warnings that you can still get the right answers using either & or &&, but one does not equal the other and could cause problems later. This is why I need clarification (also, it's just good stuff to know).
UPDATE: Since this was tagged as a duplicate, I'll clarify my intent: I want to know more about & and &&, why you use one and not the other, as well as the same info for ^, | and ||. The tagged thread has examples of using one versus another, but they don't explain the details of the operations themselves. As I'm struggling with understanding the very nature of the operations themselves, those explanations are crucial; examples alone won't clarify my understanding.
This isn't something you use bit operators for. You want to compare input string with a desired 'M' or 'F' so all you have to do is:
while (toupper(sex) != 'M' && toupper(sex) != 'F') {...
In your code you were missing the second toupper(sex) != part. You need to look at this statement as two requirements that have to be met in order for while to continue.
First one is: toupper(sex) != 'M'
Second on: toupper(sex) != 'F'
The reason why a &&(logical and) should be between those two is because you want the while loop to run if sex isn't M and at the same time it isn't F.
Operators like & and | are for comparing bits of a variable. For example if you want to use bit flags you set each of your flag to one bit and compare the resulting flag combination with &.
EDIT: So for bit flags, they compare the value you give them bit by bit. So what you do for bit flags is you can define them as powers of 2 (1, 2, 4, 8...) which each represents on position in binary (00000001, 00000010, 00000100, 00001000 ...). So for example when you have flags:
a = 1;
b = 2;
c = 4;
You can set them with ``| to your set of flags:
setFlags = setFlags | a | c;
This will compare the setFlags bit by bit with a and c.
00000000
|00000001 // a
|00000100 // c
=00000101 // result
So the | operator checks all the bits of the same position and if one of them is true, the result will be true just like logical OR.
Now to read them you use & like this:
if (setFlags & a)
which does:
00000101 // setFlags
&00000001 // a
=00000001 // result
this leaves only bits where they both are true (just like logical AND), therefore you can get true if the setFlags contains that flag.
00000101 // setFlags
&00000010 // b
=00000000 // result
in this case there are no bits set to true on same position so the result tells you that b isn't set in setFlags.
while (toupper(sex) != 'M' && 'F') is evaluated as:
while(true && (bool)'F'): while(true && true) // or
while(false && (bool)'F'): while(false && true)
because if you sex is assigned 'm' or 'M' then the condition is true and you used logical and && on a non-zero value 'f' the result is always true.
it is like: if( (bool)5 ) which is true because the bool values of any non-zero value is always true.
to correct you example:
while (toupper(sex) != 'M' && toupper(sex) != 'F')
logical operators like logical and &&, logical or ||,... return bool values true or false; 1 or 0 they evaluate expressions.
bitwise operators like bitwise and &, bitwise or |... return any value, the y work on bits:
unsigned char uc1 = 13; // 0x01 00001101
unsigned char uc2 = 11; // 0x03 00001011
unsigned char uc3 = (uc1 & uc2);// 00001001
as you can see 1 & 1 = 1, 0 & 1 = 0, 1 & 0 = 0, 1 & 1 = 1, 0 & 0 = 0...
the result us 00001001 which is in decimal 9
Related
Using C++/WinRT, Bluetooth LE, VS2017, Win10
I have a characteristic in my Bluetooth LE device that is Readable and Writable.
When checking the properties of various characteristics of a service with something like:
if (characteristic.CharacteristicProperties() == GattCharacteristicProperties::Write)
{
std::wcout << "IsWriteable = true; ";
}
The Read/Write characteristic will not get hit with ::Write and will not get hit with ::Read. The docs say that
This enumeration supports a bitwise combination of its member values.
So I tried the AND & operator since this is Read AND Write
if (characteristic.CharacteristicProperties() == (GattCharacteristicProperties::Read & GattCharacteristicProperties::Write))
{
std::wcout << "IsReadWrite = true; ";
}
However, that did not get hit either. The enumerated value of Read is 2 and of Write is 8 and in Debug this characteristic property showed as "Read | Write (10)". So I used the OR | operator in the snippet above and that hit.
My question is, why would the ::Read not hit and the ::Write not hit but the ::Read OR ::Write hit and the ::Read AND ::Write not hit?
Just kinda curious since this doesn't make sense to me.
That's not how bitwise logic operators work. When you say CharacteristicProperties() == (Read & Write), that doesn't mean must be equal to Read AND Write. What it means is to compare the value against the result of performing a bitwise AND on Read and Write. Those values are b0010 and b1000 (in binary notation), and the operation returns the value 0.
What you meant to implement was a check whether both bits are set. That is done by performing a bitwise OR operation on the flags, and compare that result:
if (characteristic.CharacteristicProperties() == (GattCharacteristicProperties::Read | GattCharacteristicProperties::Write))
{
std::wcout << "IsReadWrite = true; ";
}
This verifies whether properties is exactly equal to the combination of Read and Write flags.
Although it is more common to check whether those flags are set (possibly in addition to other flags). Using p, r, and w for the properties, read, and write flags, the following expression does that:
auto const mask = r | w;
if ((p & mask) == mask) { ... }
Another common operation is verifying whether any flags of a set of given flags are set, e.g.
auto const mask = r | w;
if ((p & mask) != 0) { ... }
This is basic bit checking.
enum { Flag1 = 2, Flag2 = 8 };
To check a single bit: if (x & Flag1) ...
To check if any of two bits are set: if (x & (Flag1 | Flag2)) ...
To check if both bits are set: if ((x & (Flag1 | Flag2)) == (Flag1 | Flag2)) ...
The previous check can be rewritten as:
auto const bits = Flag1 | Flag2;
if ((x & bits) == bits)...
In your case, Flag1 & Flag2 is always 0 (2 & 8 is 0).
x == (Flag1 | Flag2) only works if x does not contain other bits (that are irrelevant flags). 2 | 8 is 10.
I saw a post on CodeProject that helped me see the logic in the bitwise operators. I was thinking in terms of the C++ && || logic but the CodeProject post had this
The CodeProject table doesn't copy and paste here but it showed:
A = 0011, B = 0101
A and B = 0001 (ie what is in both A and B)
A or B = 0111 (ie what is in both A or B)
I believe this was mentioned in so many words above but this simple table was what my brain needed to see the binary logic.
I've spent too many brain cycles on this over the last day.
I'm trying to come up with a set of bitwise operations that may re-implement the following condition:
uint8_t a, b;
uint8_t c, d;
uint8_t e, f;
...
bool result = (a == 0xff || a == b) && (c == 0xff || c == d) && (e == 0xff || e == f);
Code I'm looking at has four of these expressions, short-circuit &&ed together (as above).
I know this is an esoteric question, but the short-circuit nature of this and the timing of the above code in a tight loop makes the lack of predictable time a royal pain, and quite frankly, it seems to really suck on architectures where branch prediction isn't available, or so well implemented.
Is there such a beast that would be concise?
So, if you really want to do bit-twiddling to make this "fast" (which you really should only do after profiling your code to make sure this is a bottleneck), what you want to do is vectorize this by packing all the values together into a wider word so you can do all the comparisons at once (one instruction), and then extract the answer from a few bits.
There are a few tricks to this. To compare two value for equality, you can xor (^) them and test to see if the result is zero. To test a field of a wider word to see if it is zero, you can 'pack' it with a 1 bit above, then subtract one and see if the extra bit you added is still 1 -- if it is now 0, the value of the field was zero.
Putting all this together, you want to do 6 8-bit compares at once. You can pack these values into 9 bit fields in a 64-bit word (9 bits to get that extra 1 guard bit your going to test for subtraction). You can fit up to 7 such 9 bit fields in a 64 bit int, so no problem
// pack 6 9-bit values into a word
#define VEC6x9(A,B,C,D,E,F) (((uint64_t)(A) << 45) | ((uint64_t)(B) << 36) | ((uint64_t)(C) << 27) | ((uint64_t)(D) << 18) | ((uint64_t)(E) << 9) | (uint64_t)(F))
// the two values to compare
uint64_t v1 = VEC6x9(a, a, c, c, e, e);
uint64_t v2 = VEC6x9(b, 0xff, d, 0xff, f, 0xff);
uint64_t guard_bits = VEC6x9(0x100, 0x100, 0x100, 0x100, 0x100, 0x100);
uint64_t ones = VEC6x9(1, 1, 1, 1, 1, 1);
uint64_t alt_guard_bits = VEC6x9(0, 0x100, 0, 0x100, 0, 0x100);
// do the comparisons in parallel
uint64_t res_vec = ((v1 ^ v2) | guard_bits) - ones;
// mask off the bits we'll ignore (optional for clarity, not needed for correctness)
res_vec &= ~guard_bits;
// do the 3 OR ops in parallel
res_vec &= res_vec >> 9;
// get the result
bool result = (res_vec & alt_guard_bits) == 0;
The ORs and ANDs at the end are 'backwards' becuase the result bit for each comparison is 0 if the comparison was true (values were equal) and 1 if it was false (values were not equal.)
All of the above is mostly of interest if you are writing a compiler -- its how you end up implementing a vector comparison -- and it may well be the case that a vectorizing compiler will do it all for you automatically.
This can be much more efficient if you can arrange to have your initial values pre-packed into vectors. This may in turn influence your choice of data structures and allowable values -- if you arrange for your values to be 7-bit or 15-bit (instead of 8-bit) they may pack nicer when you add the guard bits...
You could modify how you store and interpret the data:
When a if 0xFF, do you need the value of b. If not, then make b equal to 0xFF and simplify the expression by removing the part that test for 0xFF.
Also, you might combine a, b and c in a single variable.
uint32_t abc;
uint32_t def;
bool result = abc == def;
Other operations might be slower but that loop should be much faster (single comparison instead of up to 6 comparisons).
You might want to use an union to be able to access byte individually or in group. In that case, make sure that the forth byte is always 0.
To remove timing variations with &&, ||, use &, |. #molbdnilo. Possible faster, maybe not. Certainly easier to parallel.
// bool result = (a == 0xff || a == b) && (c == 0xff || c == d)
// && (e == 0xff || e == f);
bool result = ((a == 0xff) | (a == b)) & ((c == 0xff) | (c == d))
& ((e == 0xff) | (e == f));
Is there a quick bit operation to implement msb_equal: a function to check if two numbers have the same most significant bit?
For example, 0b000100 and 0b000111 both have 4 as their most significant bit value, so they are most msb_equal. In contrast 0b001111 has 8 as the MSB value, and 0b010000 has 16 as it's MSB value, so the pair are not msb_equal.
Similarly, are there fast ways to compute <, and <=?
Examples:
msb_equal(0, 0) => true
msb_equal(2, 3) => true
msb_equal(0, 1) => false
msb_equal(1, 2) => false
msb_equal(3, 4) => false
msb_equal(128, 255) => true
A comment asks why 0 and 1 are not msb_equal. My view on this is that if I write out two numbers in binary, they are msb_equal when the most significant 1 bit in each is the same bit.
Writing out 2 & 3:
2 == b0010
3 == b0011
In this case, the top most 1 is the same in each number
Writing out 1 & 0:
1 == b0001
0 == b0000
Here, the top most 1s are not the same.
It could be said that as 0 has no top most set bit, msb_equal(0,0) is ambiguous. I'm defining it as true: I feel this is helpful and consistent.
Yes, there are fast bit based operations to compute MSB equality and inequalities.
Note on syntax
I'll provide implementations using c language syntax for bitwise and logical operators:
| – bitwise OR. || – logical OR.
& – bitwise AND. && – logical AND.
^ – bitwise XOR.
==
msb_equal(l, r) -> bool
{
return (l^r) <= (l&r)
}
<
This is taken from the Wikipedia page on the Z Order Curve (which is awesome):
msb_less_than(l, r) -> bool
{
(l < r) && (l < l^r)
}
<=
msb_less_than_equal(l, r) -> bool
{
(l < r) || (l^r <= l&r)
}
If you know which number is the smallest/biggest one, there is a very fast way to check whether the MSBs are equal. The following code is written in C:
bool msb_equal(unsigned small, unsigned big) {
assert(small <= big);
return (small ^ big) <= small;
}
This can be useful in cases like when you add numbers to a variable and you want to know when you reached a new power of 2.
Explanation
The trick here is that if the two numbers have the same most significant bit, it will disappear since 1 xor 1 is 0; that makes the xor result smaller than both numbers. If they have different most significant bits, the biggest number's MSB will remain because the smallest number has a 0 in that place and therefore the xor result will be bigger than the smallest number.
When both input numbers are 0, the xor result will be 0 and the function will return true. If you want 0 and 0 to count as having different MSBs then you can replace <= with <.
This question already has answers here:
Why can't we use bitwise operators on float & double data types
(2 answers)
Closed 7 years ago.
These are two simple samples in C++ written on Dev-cpp C++ 5.4.2:
float a, b, c;
if (a | b & a | c)
printf("x = %.2f\tF = %.0f\n", x, F);
else
printf("x = %.2f\tF = %.2f\n", x, F);
and this code :
float a, b, c;
if (a || b && a || c)
printf("x = %.2f\tF = %.0f\n", x, F);
else
printf("x = %.2f\tF = %.2f\n", x, F);
Can somebody tell my difference between || > | and & > &&. The second code works , but first does not.
And compiler gives an error message :
[Error] invalid operands of types 'float' and 'float' to binary 'operator&'.
The operators |, &, and ~ act on individual bits in parallel. They can be used only on integer types. a | b does an independent OR operation of each bit of a with the corresponding bit of b to generate that bit of the result.
The operators ||, &&, and ! act on each entire operand as a single true/false value. Any data type can be used that implicitly converts to bool. Many data types, including float implicitly convert to bool with an implied !=0 operation.
|| and && also "short circuit". That means whenever the value of the result can be determined by just the first operand, the second is not evaluated. Example:
ptr && (*ptr==7) If ptr is zero, the result is false without any risk of seg faulting by dereferencing zero.
You could contrast that with (int)ptr & (*ptr). Ignoring the fact that this would be a bizarre operation to even want, if (int)ptr were zero, the entire result would be zero, so a human might think you don't need the second operand in that case. But the program will likely compute both anyway.
You seems be confused with the symbols of the operators. Theses symbols are actually split in two different categories, which are bit-wise operators and logical operators. Although they use the same symbols, you should regard them as different operators. The truth tables for both categories are similar, but the meanings are different. Maybe that's why people use the similar symbols for the operators.
bit-wise operators
~ // NOT
& // AND
| // OR
^ // XOR
The bit-wise operators will regard all its operands as binary numerals and act according to the bit-wise truth tables on every bit of the operands.
Bit-wise Truth Table
x y x&y x|y x^y
0 0 0 0 0
1 0 0 1 1
0 1 0 1 1
1 1 1 1 0
x ~x
0 1
1 0
logical operators
! // Logical NOT (negation)
&& // Logical AND (conjunction)
|| // Logical OR (disjunction)
The logical operator will regard all its operands as bools and act according the operator truth tables. Any number that is not equal to 0 will be true, else will be false.
Logical Truth Table
x y x&&y x||y
F F F F
T F F T
F T F T
T T T T
x !x
F T
T F
For example:
int a = 10; // a = 0000 .... 0000 1010 <-- a 32 bits integer
// a is not zero -> true
int b = 7; // b = 0000 .... 0000 0111 <-- a 32 bits integer
// b is not zero -> true
Then for bit-wise operator:
assert(a & b == 2); // 2 = 0000 .... 0000 0010 <-- every bit will & separately
For logic operator:
assert(a && b == true); // true && true -> true
The bitwise operators, which are | (OR), & (AND), ^ (XOR), and ~ (complement) do what you expect them to do: they perform the aforementioned operations on bits.
And regarding your compilation issue, there are no bitwise operations for floating point numbers.
The logical operators, which are || (OR), && (AND), and ! (NOT) only know the values true and false.
An expression is true if its value is not 0. It is false if its value equals 0.
The logical operators do this operation first. Then they perform their corresponding operation:
||: true if at least one the operands is true
&&: true if both operands are true
!: true if the operand is false
Note that all logical operators are short-circuit operators.
Bitwise operation is not supported for floating points
Alternatively if you really need to check, you can cast before you use them (highly discouraged),
Check here how to convert a float into integrals, https://www.cs.tut.fi/~jkorpela/round.html
I am trying to learn C programming, and I was studying some source codes and there are some things I didn't understand, especially regarding Bitwise Operators. I read some sites on this, and I kinda got an idea on what they do, but when I went back to look at this codes, I could not understand why and how where they used.
My first question is not related to bitwise operators but rather some ascii magic:
Can somebody explain to me how the following code works?
char a = 3;
int x = a - '0';
I understand this is done to convert a char into an int, however I don't understand the logic behind it. Why/How does it work?
Now, Regarding Bitwise operators, I feel really lost here.
What does this code do?
if (~pointer->intX & (1 << i)) { c++; n = i; }
I read somewhere that ~ inverts bits, but I fail to see what this statement is doing and why is it doing that.
Same with this line:
row.data = ~(1 << i);
Other question:
if (x != a)
{
ret |= ROW;
}
What exactly is the |= operator doing? From what I read, |= is OR but i don't quite understand what is this statement doing.
Is there any way of rewriting this code to make it easier to understands so that it doesn't use this bitwise operators? I find them very confusing to understand, so hopefully somebody will point me in the right direction on understanding how they work better!
I have a much better understanding of bitwise operators now and the whole code makes much more sense now.
One last thing: appartenly nobody responded if there would be a "cleaner" way for rewriting this code in a way that its easier to understand and maybe not at "bitlevel". Any ideas?
This will produce junk:
char a = 3;
int x = a - '0';
This is different - note the quotes:
char a = '3';
int x = a - '0';
The char datatype stores a number that identifiers a character. The characters for the digits 0 through 9 are all next to each other in the character code list, so if you subtract the code for '0' from the code for '9', you get the answer 9. So this will turn a digit character code into the integer value of the digit.
(~pointer->intX & (1 << i))
That will be interpreted by the if statement as true if it's non-zero. There are three different bitwise operators being used.
The ~ operator flips all the bits in the number, so if pointer->intX was 01101010, then ~pointer->intX will be 10010101. (Note that throughout, I'm illustrating the contents of a byte. If it was a 32-bit integer, I'd have to write 32 digits of 1s and 0s).
The & operator combines two numbers into one number, by dealing with each bit separately. The resulting bit is only 1 if both the input bits are 1. So if the left side is 00101001 and the right side is 00001011, the result will be 00001001.
Finally, << means left shift. If you start with 00000001 and left shift it by three places, you'll have 00001000. So the expression (1 << i) produces a value where bit i is switched on, and the others are all switch off.
Putting it all together, it tests if bit i is switched off (zero) in pointer->intX.
So you may be able to figure out what ~(1 << i) does. If i is 4, the thing in brackets will be 00010000, and so the whole thing will be 11101111.
ret |= ROW;
That one is equivalent to:
ret = ret | ROW;
The | operator is like & except that the resulting bit is 1 if either of the input bits is 1. So if ret is 00100000 and ROW is 00000010, the result will be 00100010.
ret |= ROW;
is equivalent to
ret = ret | ROW;
For char a = 3; int x = a - '0'; I think you meant char a = '3'; int x = a - '0';. It's easy enough to understand if you realize that in ASCII the numbers come in order, like '0', '1', '2', ... So if '0' is 48 and '1' is 49, then '1' - '0' is 1.
For bitwise operations, they are hard to grasp until you start looking at bits. When you view these operations on binary numbers then you can see exactly how they work...
010 & 111 = 010
010 | 111 = 111
010 ^ 111 = 101
~010 = 101
I think you probably have a typo, and meant:
char a = '3';
The reason this works is that all the numbers come in order, and '0' is the first. Obviously, '0' - '0' = 0. '1' - '0' = 1, since the character value for '1' is one greater than the character value for '0'. Etc.
1) A char is really just a 8-bit integer. '0' == 48, and all that that implies.
2) (~(pointer->intX) & (1 << i)) evalutates whether the 'i'th bit (from the right) in the intX member of whatever pointer points to is not set. The ~ inverts the bits, so all the 0s become 1s and vice versa, then the 1 << i puts a single 1 in the desired location, & combines the two values so that only the desired bit is kept, and the whole thing evalutes to true if that bit was 0 to begin with.
3) | is bitwise or. It takes each bit in both operands and performs a logical OR, producing a result where each bit is set if either operand had that bit set. 0b11000000 | 0b00000011 == 0b11000011. |= is an assignment operator, in the same way that a+=b means a=a+b, a|=b means a=a|b.
Not using bitwise operators CAN make things easier to read in some cases, but it will usually also make your code significantly slower without strong compiler optimization.
The subtraction trick you reference works because ASCII numbers are arranged in ascending order, starting with zero. So if ASCII '0' is a value of 48 (and it is), then '1' is a value of 49, '2' is 50, etc. Therefore ASCII('1') - ASCII('0') = 49 - 48 = 1.
As far as bitwise operators go, they allow you to perform bit-level operations on variables.
Let's break down your example:
(1 << i) -- this is left-shifting the constant 1 by i bits. So if i=0, the result is decimal 1. If i = 1, it shifts the bit one to the left, backfilling with zeros, yielding binary 0010, or decimal 2. If i = 2, you shift the bit two to the left, backfilling with zeros, yielding binary 0100 or decimal 4, etc.
~pointer->intX -- this is taking the value of the intX member of pointer and inverting its bits, setting all zeros to ones and vice versa.
& -- the ampersand operator does a bitwise AND comparison. The results of this will be 1 wherever both the left and right side of the expression are 1, and 0 otherwise.
So the test will succeed if pointer->intX has a 0 bit at the ith position from the right.
Also, |= means to do a bitwise OR comparison and assign the result to the left side of the expression. The result of a bitwise OR is 1 for every bit where the corresponding left or right side bit is 1,
Single quotes are used to indicate that a single char is used. '0' therefore is the char '0', which has the ASCII-Code 48.
3-'0'=3-48
'1<<i' shifts 1 i places to the left, therefore only the ith bit from the right is 1.
~pointer->intX negates the field intX, so the logical AND returns a true value (not 0) when intX has every bit except for the ith bit from the right isn't set.
char a = '3';
int x = a - '0';
you had a typo here (notice the 's around the 3), this assigns the ascii value of the character 3, to the char variable, then the next line takes '3' - '0' and assigns it to x, because of the way ascii values work, x will then be equal to 3 (integer value)
In the first comparison, I've never seen ~ being used on a pointer that way before, another typo maybe? If I were to read out the following code:
(~pointer->intX & (1 << i))
I would say "(the value intX dereferenced from pointer) AND (1 left shifted i times)"
1 << i is a quick way of multiplying 1 by a power of 2, ie if i is 3, then 1 << 3 == 8
In this case, I have no clue why you would invert the bits of the pointer..
In the 2nd comparison, x |= y is the same as x = x | y
I'm assuming you mean char a='3'; for the first line of code (otherwise you get a rather strange answer). The basic principal is that ASCII codes for digits are sequential, i.e. the code for '0'=48, the code for '1'=49, and so on. Subtracting '0' simply converts from the ASCII code to the actual digit, so e.g. '3' - '0' = 3, and so on. Note that this will only work if the character you're subtracting '0' from is an actual digit - otherwise the result will have little meaning.
a. Without context the "why" of this code is impossible to say. As for what it's doing, it appears that the if statement evaluates as true when bit i of pointer->intX is not set, i.e. that particular bit is a 0. I believe the & operator gets executed before the ~ operator, as the ~ operator has very low precedence. The code could make better use of parentheses to make the intended order of operations clearer. In this case, the order of operations might not matter though - I believe the result is the same either way.
b. This is simply creating a number with all bits EXCEPT bit i set to 1. A convenient way of creating a mask for bit i is to use the expression (1<<i).
The bitwise OR operation in this case is used to set the bits specified by the ROW constant to 1. If these bits are not set, it sets them; if they're already set it has no effect.
1) Can somebody explain to me how the following code works? char a = 3; int x = a - '0';
I undertand this is done to convert a char into an int, however I don't understand the logic behind it. Why/How does it work?
Sure. variable a is of type char, and by putting single quotes around 0 that is causing C to view it as a char as well. Finally, the whole statement is automagically typecast to its integer equivalent, because x is defined as an integer.
2) Now, Regarding Bitwise operators, I feel really lost here.
--- What does this code do? if (~pointer->intX & (1 << i)) { c++; n = i; } I read somewhere that ~ inverts bits, but I fail to see what this statement is doing and why is it doing that.
(~pointer->intX & (1 << i)) is saying:
negate intX, and AND it with a 1 shifted left by i bits
so, what you're getting, if intX = 1011, and i = 2, equates to
(0100 & 0100)
-negate 1011 = 0100
-(1 << 2) = 0100
0100 & 0100 = 1 :)
then, if the AND operation returns a 1 (which, in my example, it does)
{ c++; n = i; }
so, increment c by 1, and set variable n to be i
Same with this line: row.data = ~(1 << i);
Same principle here.
Shift a 1 to the left by i places, and negate.
So, if i = 2 again
(1 << 2) = 0100
~(0100) = 1011
**--- Other question:
if (x != a) { ret |= ROW; }
What exacly is the |= operator doing? From what I read, |= is OR but i don't quite understand what is this statement doing.**
if (x != a) (hopefully this is apparent to you....if variable x does not equal variable a)
ret |= ROW;
equates to
ret = ret | ROW;
which means, binary OR ret with ROW
For examples of exactly what AND and OR operations accomplish, you should have a decent understanding of binary logic.
Check wikipedia for truth tables...ie
Bitwise operations