![]() |
|
This thread is locked; no one can reply to it.
![]() ![]() |
1
2
|
logical vs. binary operators |
Martin Kalbfuß
Member #9,131
October 2007
![]() |
Hi, I realised that the the logical operators && and || are doing the same as & and |. int res1 = 5 == 5 && 3 < 4 int res2 = 5 == 5 & 3 < 4 return the same result. I always used them without thinking about their difference. So why do I need extra operators for logical operations? Thanks http://remote-lisp.spdns.de -- my server side lisp interpreter |
anonymous
Member #8025
November 2006
|
Short circuiting on logical operators. And you have to be careful to use the binary operators only with boolean values or you won't get the same results.
|
Matthew Leverton
Supreme Loser
January 1999
![]() |
& is binary: 0 & 0 = 0 0 & 1 = 0 1 & 0 = 0 1 & 1 = 1 So if both sides of (foo == 1) & (bar == 2) evaluate to true, then the expression is true. But that only works with boolean values. Consider: if (1 & 2) { // not true } if (1 && 2) { // true } Also, logical operators will short circuit. 1int t()
2{
3 return 1;
4}
5
6int f()
7{
8 fire_nukes();
9 return 0;
10}
11
12if (t() || f())
13{
14 // world is safe ... f() never called
15}
16
17if (t() | f())
18{
19 // world is blown up
20}
They are used for different things ... although many times they are interchangeable. |
Arthur Kalliokoski
Second in Command
February 2005
![]() |
Or to rephrase: 001001001 binary A bitwise or'ed with (|) 000100001 binary B --------- 001101001 Return all bits that are set as in "Is this particular bit set in A or B?" Not the same as asking little Tommy if he wants cake OR ice cream for dessert and he says "Yes" (Exclusive OR is what was wanted there) 001001001 binary A logically or'ed with {||) 000100001 binary B --------------- NNYYNYNNY <- where N means neither bit is set, and Y means at least one bit is set, and Yes overrides No. Since one or more Yes'es are there, return TRUE or 1.
They all watch too much MSNBC... they get ideas. |
Tobias Dammers
Member #2,604
August 2002
![]() |
Martin Kalbfuß said: I realised that the the logical operators && and || are doing the same as & and |. They don't.
The logical operators evaluate each operand as a boolean, perform their logic on them, and return a boolean. --- |
tobing
Member #5,213
November 2004
![]() |
Oops. & is a bit-wise operation on the operands, i.e. the result has a bit set only if both operands have the same bit set. && is a logical operation on two bool values and is true only if both operands evaluate to true. | is a bit-wise operation, a bit in the result is set if the corresponding bit is set in one of both operands. || again is a logical operation between two bool operands. So considering the bit-representation of numbers, you get 5 | 8 = 13, 5 | 7 = 5, 5 & 8 = 0, 5 & 7 = 5. |
ImLeftFooted
Member #3,935
October 2003
![]() |
I think | is always the same as ||... (in a condition) |
Kitty Cat
Member #2,815
October 2002
![]() |
|| gives a boolean result, | gives an integer.. if((a || b) == (c || d)) ... // vs if((a | b) == (c | d)) ...
-- |
Audric
Member #907
January 2001
|
Dustin: If both operands are booleans (only values 0x00000001 and 0x00000000), and if there are no side effects of evaluating the right one, and if you only care if the result equals zero; then yes, you get the same result. Note that under the same conditions, + is the same as || |
ImLeftFooted
Member #3,935
October 2003
![]() |
Audric said: Note that under the same conditions, + is the same as || I dunno, not really. if(UINT_MAX + 1) // nope While if(UINT_MAX | 1) // yup My main point was that he probably thought | -> || and & -> && were equivalent because effectively | -> || really is. It would be logical (without knowing more) that & would expand to && as well, especially because it does if you're lucky. |
Arthur Kalliokoski
Second in Command
February 2005
![]() |
Doesn't C++ require Booleans to be 1... uh, or 0 exclusively? 4 | 6 isn't the same as 4 || 6 then. They all watch too much MSNBC... they get ideas. |
Jonatan Hedborg
Member #4,886
July 2004
![]() |
| still does not short circuit.
|
Kitty Cat
Member #2,815
October 2002
![]() |
Arthur Kalliokoski said: Doesn't C++ require Booleans to be 1... uh, or 0 exclusively? From what I remember being told, bools in C++ are not numbers, but are either true or false. Nothing else. False is interpreted as integer 0 (same as NULL is interpreted as integer 0, even if the NULL address is not 0x00000000), and true is a non-0 integer. Most compilers will use 1, but -1 and 124354245 are just as valid. -- |
Arthur Kalliokoski
Second in Command
February 2005
![]() |
Sorry, I was misremembering what I'd read in http://www.agner.org/optimize/optimizing_cpp.pdf. Quote:
Boolean variables are stored as 8-bit integers with the value 0 for false and 1 for true.
They all watch too much MSNBC... they get ideas. |
Audric
Member #907
January 2001
|
Dustin: I said "under the same conditions".... UINT_MAX is not equal to 0x00000001 or 0x00000000. Unrelatedly, here are two valid uses of the operators, where you really shouldn't mistake one for the other. // Use high quality sprite if available, or use the normal one. // (If there was a big problem, none is available, so use a generic "missing" sprite) BITMAP *sprite = high_quality_sprite || normal_quality_sprite || sprite_missing; ... // Store multiple related booleans in a single field. this->Collision_flags = COLLISION_SOLID | COLLISION_GRAVITY | COLLISION_PUSHABLE;
|
Kitty Cat
Member #2,815
October 2002
![]() |
Audric
Member #907
January 2001
|
What did I miss ? Associativity is left-to-right, I just checked. I admit it's not a construct I actually use, so I'd rather know what's the mistake. |
Arthur Kalliokoski
Second in Command
February 2005
![]() |
You're messing with the address of the bitmap struct location, not setting attributes. They all watch too much MSNBC... they get ideas. |
Jonatan Hedborg
Member #4,886
July 2004
![]() |
That should not matter. If the first one is zero, the next one will be returned (etc). I can't see why that would fail... Though I only ever used it in actionScript and ruby.
|
Audric
Member #907
January 2001
|
Arthur Kalliokoski: That was my intention... the two examples are not necessarily related. When I wrote the second I was tempted to rewrite the first as "this->sprite = ...", but then you wouldn't see that the type of "sprite" is "BITMAP *", and this seemed required for understanding... |
Tobias Dammers
Member #2,604
August 2002
![]() |
Arthur Kalliokoski said: Doesn't C++ require Booleans to be 1... uh, or 0 exclusively? 4 | 6 isn't the same as 4 || 6 then.
No. It requires boolean false to evaluate to zero when cast to integer, and boolean true to something non-zero. 1 is common, but AFAIK any other non-zero value would be valid too. The important thing is that when you cast a boolean to int and then back to boolean, the original value must be retained. The most important point IMO however is readability. Use the distinction between logical and bit-wise operator to clearly indicate your intention, even if they happen to be interchangeable. --- |
Matthew Leverton
Supreme Loser
January 1999
![]() |
Jonatan Hedborg said: That should not matter. If the first one is zero, the next one will be returned (etc). I can't see why that would fail... Though I only ever used it in actionScript and ruby. printf("%d\n", 10 || 20 || 30); What do you expect that to display (in C/C++)? Correct Answer: 1
|
Jonatan Hedborg
Member #4,886
July 2004
![]() |
Oh that's intresting. Never tried it in C/C++, just assumed it worked as in other languages
|
Thomas Fjellstrom
Member #476
June 2000
![]() |
Indeed boolean operators evaluate to a boolean value. ie: 0 or 1. -- |
Ron Novy
Member #6,982
March 2006
![]() |
It's simple when you think about it like this. Boolean operators are either equal to 0 (FALSE) or not equal to zero (TRUE)... So any value that is not zero is TRUE. 1int x = 0; /* == FALSE */
2int y = 10; /* == TRUE */
3int z = -30; /* == TRUE */
4
5if (x)
6 printf("x == 1 == TRUE\n); // <- This string is never displayed because x == 0
7
8if (z)
9 printf("z == 1 == TRUE\n"); // <- z evaluates to TRUE or 1 (same with y).
10
11if (x || y)
12 printf("x || y == 1 == TRUE\n");
13
14if (x && y)
15 printf("x && y == 1 == TRUE"); // <- This string is never displayed...
16
17if (!x && z)
18 printf("!x && z == TRUE\n"); // <- !x == 1 and z == 1 so this is displayed.
Bottom line is, the two types of OR and AND operators should not be confused with each other. You will get unexpected results... [edit]Arg... I was too slow... ---- |
|
1
2
|