What is the difference between & and && in C?
My teacher gave me this example:
int a = 8;
int b = 4;
printf("a & b = %d\n", a & b);
printf("a && b = %d\n", a && b);
Output:
a & b = 0;
a && b = 1;
I'm not sure why this would return true in one scenario and false in another.
& is bitwise and and && is logical and.
The expression x && y will return 1 if both x and y is non-zero, and 0 otherwise. Note that if x is zero, then y will not be evaluated at all. This will matter if y is an expression with side effects. This behviour is called short circuiting.
The expression x & y will perform a bitwise operation on each individual bit in x and y. So if x is 1010 in binary and y is 1100 then x & y will evaluate to 1000. Note that the return value of x & y should NOT be interpreted as a Boolean value, even if it's possible. In early C, the operator && did not exist, and because of that & was used for this purpose.
One way to explain it is that you could imagine that & is the same thing as applying && on each individual bit in the operands.
Also note that & has lower precedence than &&, even though intuition says that it should be the other way around. This also goes for comparison operators, like <, <=, ==, !=, >=, >. This goes back to the time when C did not have the operators && and || and the bitwise versions was used instead. At this time, it made sense, but when the logical operators were added, it did not anymore. Kernighan and Ritchie admitted that it would have made more sense, but they did not fix it because this would break existing code.
I'm not sure why this would return true in one scenario and false in another.
The return value from x & y should not be treated as a Boolean value at all. However, it can (depending on how the code is written) be treated as a Boolean array. If you have two integers, flags1 and flags2 then the result of flags1 & flags2 will denote which flags that are toggled in both flags1 and flags2.
The & operator performs a bit-wise and operation on its integer operands, producing an integer result. Thus (8 & 4) is (0b00001000 bitand 0b00000100) (using a binary notation that does not exist in standard C, for clarity), which results in 0b00000000 or 0.
The && operator performs a logical and operation on its boolean operands, producing a boolean result. Thus (8 && 4) is equivalent to ((8 != 0) and (4 != 0)), or (true and true), which results in true.
&& (logical and operator) - The left and right operands are boolean expressions. If both the operands are non-zero, then the condition becomes true.
>
& (bitwise and operator) - The left and right operands are integral types. Binary AND Operator copies a bit to the result if it exists in both operands.
In your teacher's example a && b, the left operand 4 and the right operand 8 are both non-zero. So the condition will become true.
In your teacher's other example a & b, the left operand 4 or 0100 and the right operand 8 or 01000 copies no bits to the result. This is because there are no common set bits in either operand.
& is bitwise operator and, && is logical for example if you use two number and you want to use bitwise operator you can write & .
if you want to use to phrase and you want to treat them logically you can use && .
Related
Why C has both || and | operators? As far I know, | operator can replace || in conditions because it will return true (nonzero) value when at least one of operands is nonzero.
I ask just out of my curiosity. I know I should use || for logical expressions.
Example
#include <stdio.h>
int main(void) {
int to_compare = 5;
/* Try with bitwise or */
if ((5 > to_compare) | (to_compare == 6)) {
printf("‘to_compare’ is less than or equal to 5 or equal to 6.\n");
}
/* Try with logical or */
if ((5 > to_compare) || (to_compare == 6)) {
printf("‘to_compare’ is less than or equal to 5 or equal to 6.\n");
}
return 0;
}
|| and | are very different beasts.
Aside from || having the short-circuting property (the right operand is only evaluted if the left one evaluates to 0), it's also a sequencing point.
The value of the expression can also be different: 1 || 2 for example is 1 whereas 1 | 2 is 3.
(Note that && and & have a more pernicious difference, for example 1 && 2 is 1 whereas 1 & 2 is 0.)
In addition to the fact that the || operator is short-circuiting, the result of the || operator is always either 0 or 1 based on its truth, whereas the result of the bitwise or | operator will be a combination of bits that were set in the operands, which is not necessarily 1 (i.e. 0x0A | 0xB0 = 0xBA, whereas 0x0A || 0xB0 = 1.
§6.5.14 Logical OR operator
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
§6.5.12 Bitwise inclusive OR operator
The result of the | operator is the bitwise inclusive OR of the operands (that is, each bit in
the result is set if and only if at least one of the corresponding bits in the converted
operands is set).
In BCPL and B -- C ancestors --, there is only | and &. But their interpretation is dependent on the context: in control structures like if, they behaved like the C logical operators, in other contexts, they behaved like the C binary operators. That was deemed too difficult to use and explain and thus additional operators where introduced so that the operator used indicated clearly if the operation was logical and short-circuiting, or binary and not short-circuiting. And that also explains the inconvenient relative priorities with comparison operators.
Please consider these piece of C code:
if ((value & 1) == 1)
{
}
Assuming value equals 1, will (value & 1) return 1 or any unspecified non zero number?
§6.5.8 Relational operators
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.) The result has type int.
§6.5.9 Equality operators
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. For any pair of operands, exactly one of the relations is true.
§6.5.13 Logical AND operator
The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
§6.5.14 Logical OR operator
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
Does “true” in C always mean 1?
No. Any expression that evaluates to a non-zero value is "true" in C. For example,
if (-1) {
}
if (5-10) {
}
if( "string literal") {
}
are all "true" and pass the condition.
In your specific example, the relational operator == yields 1 which is also "true"(the same holds for all other relational operators as noted by Govind).
If you are really asking about whether the bit-wise AND (&) yields 1 when value is 1, then yes, value & 1 yields 1 (assuming value is an integer type -- & operator requires its operands to be integers).
In fact, you can probably try to understand the individual parts and (generally how the & and == operators behave) by using a simple program:
#include <stdio.h>
int main(void)
{
int value = 1;
printf(" value & 1 = %d\n", value & 1);
printf(" 2 & 1 = %d\n", 2 & 1);
printf("((value & 1) == 1) = %d", (value & 1) == 1);
}
strcat(b, ((x & z) == z) ? "1" : "0");
I understand strcat() function and the conditional (ternary) operator. But I don't know what (x & z) == z means.
& is the bitwise AND operator.
here, (x & z) == z means, perform a bitwise AND of x and z and if that value equals to z, then....
Ref: Chapter 6.5.10, C11 standard, "Bitwise AND operator"
The result of the binary & operator is the bitwise AND of the operands (that is, each bit in the result is set if and only if each of the corresponding bits in the converted operands is set).
The means:
Concatenate "1" to string b if bitwise And of x and z is same as z,else concatenate "0" to string b.
x&z means bitwise anding of x and z.
The result is then compared with z.
If the result is same as z then condition evaluates to be TRUE otherwise FALSE.
(x & z) == z means in 'x', ALL the bits which are SET in 'z' is SET.
'x' must contain all the bits set OR additionally some more bits may also be set. Then this condition becomes true.
Sometimes I want to do something like this (with i and j being ints).
(if i==4 && j==9)
{
...
}
Where it'll go through the brackets if i equals 4 and j equals 9. I've been using a single ampersand (&) instead of a double one and my code's been compiling and running.
Is it doing the same thing as a double ampersand &&, and if not what has it been doing?
Edit: Oh and I've been doing the same thing with or, using '|' instead of '||'
Presumably you mean if (i==4 && j==9).
Under the circumstances, changing this from && to & shouldn't change much. The big thing that'll change is that with &&, the j==9 would only be evaluated if the i==4 part was true, but with &, they'll both be evaluated regardless.
When you have something like if (x != NULL && x->whatever ...) you want to ensure that the second part (that dereferences x) is only evaluated if x is not a null pointer. In your case, however, comparing what appear to be ints is unlikely to produce any problems.
It's also possible to run into a problem when you're dealing with something that may produce a value other than 1 to signal true. Again, it's not a problem here because == will always produce either 0 or 1. If (for example) you were using isalpha, islower, etc., from <ctype.h>, they're only required to produce 0 or non-zero values. If you combined those with a &, you'd get a bit-wise or which could produce 0 for two non-zero inputs (e.g., 1 & 2 == 0, but 1 && 2 == 1).
When you use bitwise and on the results from ==, you're going to get 0 & 0 or 0 & 1 or 1 & 0 or 1 & 1. 1 & 1 will yield 1 (true). All the others will yield 0 (false) --- just like && would have.
It's performing a bitwise AND.
What it's doing is the expression i == 4 is equivalent to 1 if i is 4 and the same for the RHS (with j and 9, obviously). The & operator returns the number where both operands have that bit on.
It works the same as && because 00000001 & 00000001 (slimmed down to a byte for example) is the same. If one is 0 (the condition was false), then the & won't see two bits turned on for both operands, and 00000000 is 0, which is falsey.
However, do not simply use & because it's one character shorter or similar. Use it because it expresses what you want to achieve. If it's a logical AND you want, use &&.
The same thing applies to |, except instead of a resulting bit if each operand has it turned on, it turns it on if either operand has that bit turned on.
A single ampersand does a bitwise AND. Every bit of the result is set only if both operands have a 1 in that position.
Since comparisons in C return 1 for true and 0 for false, & will give the same results as && as long as both operands are comparisons. But for arbitrary values, it will return seemingly random results. 1 && 2 is true, but 1 & 2 is false because the binary representations of 1 and 2 have no bits in common.
A single ampersand is called a bitwise and. It is a binary operator that 'ands' two numbers bit by bit.
For instance, if you have two binary numbers, 01100010 and 00011111, your bitwise and will result in 00000010
i==4 returns 1 (true), as does j==9. So, i==4 & j==9 is really just 1 & 1, which evaluates to 1 (true).
Try these examples to see the difference
1) int k = 4 & 6; vs int k = 4 && 6;
2) if(i==4 && 2) vs if(i==4 & 2)
using only bitwise operators (|, &, ~, ^, >>, <<), is it possible to replace the != below?
// ...
if(a != b){
// Some code
}
/// ...
this is mainly out of self interest, since I saw how to do it with == but not !=.
if(a ^ b) {
//some code
}
should work.
You can also use your preferred method for == and add ^ 0xFFFFFFFF behind it (with the right amount of Fs to match the length of the datatype). This negates the value (same as ! in front of it).
a != b means that there is at least one different bit in the bit representations of a and b. The XOR bit operator returns 1 if both input bit operands are different, 0 otherwise.
So, you can apply a XOR operation to a and b and check if the result is not equal to zero.
A bitwise version of the '!=' test could look something like:
if((a - b) | (b - a)) {
/* code... */
}
which ORs the two subtractions. If the two numbers are the same, the result will be 0. However, if they differ (aka, the '!=' operator) then the result will be 1.
Note: The above snippet will only work with integers (and those integers should probably be unsigned).
If you want to simulate the '==' operator, however, check out Fabian Giesen's answer in Replacing "==" with bitwise operators
x ^ y isn't always sufficient. Use !!(x ^ y). Values expecting a one bit return value will not work with x ^ y since it leaves a remainder that could be greater than just 1.
Yes, using this:
if (a ^ b) { }
"~" is equaled to NOT so that should work. example would be "a & ~b".