Please help, simple operators problem

Can you please explain the code below? I am mostly confused about the "if" part. If there is no argument (eg. 5<8) in the if, how can it run/what does it do?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  int
main ()
{
  uint8_t In = 5, Out = 8, W = 85;

  if (In&1<<2) {
     W=In;
     Out ^= 2;
     } 
  In ^= W;
  if (!W) {
     W=Out;
     Out |= 1<<1;
     }
     else 
  Out &= ~(1 << 1);
  W ^= W;


  cout << "In: " << unsigned (In) << endl;
  cout << "Out: " << unsigned (Out) << endl;
  cout << "W:  " << unsigned (W) << endl;


}
The argument (condition being checked) is (In&1<<2).

This is the same as saying if ((In&1<<2) != 0)).

It's shifting 1 over by 2 binary places (0b1 --> 0b100), and then bit-ANDing it with In.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <cstdint>
#include <iostream>
#include <bitset>
using namespace std;

int
main ()
{
    for (uint8_t In = 0; In < 20; In++)
    {
        std::cout << std::bitset<8>(In) << " --> " << std::bitset<8>(In & 1 << 2) << '\n';
    }

}

You can see the pattern it creates:
00000000 --> 00000000
00000001 --> 00000000
00000010 --> 00000000
00000011 --> 00000000
00000100 --> 00000100
00000101 --> 00000100
00000110 --> 00000100
00000111 --> 00000100
00001000 --> 00000000
00001001 --> 00000000
00001010 --> 00000000
00001011 --> 00000000
00001100 --> 00000100
00001101 --> 00000100
00001110 --> 00000100
00001111 --> 00000100
00010000 --> 00000000
00010001 --> 00000000
00010010 --> 00000000
00010011 --> 00000000

Basically, the output will be non-zero if the 3rd digit is 1.

For the second if statement, the argument is (!W), which is the same as saying (W == 0).
The if at line 11 does have "an argument". It could have been rewritten as if (W == 0).

Boolean values can be implied from any non-Boolean value not zero as true and 0 (zero) as false. !W simply inverts (NOT) the implied value.

Thank you for using code tags, but in the future it might be a good idea to include the header files in the code snippet. You should post a Short, Self Contained, Correct (Compilable), Example if'n at all possible.

http://www.sscce.org/
Last edited on
> If there is no argument (eg. 5<8) in the if, how can it run/what does it do?

If the condition of the if statement is an expression, it is contextually converted to bool.
https://en.cppreference.com/w/cpp/language/implicit_conversion#Contextual_conversions

1
2
3
4
5
6
7
8
9
10
11
int i = 23 ;

if(i) // equivalent to if( bool(i) )
{
    // ....
}

if( std::cin ) // equivalent to if( bool(std::cin) )
{
    // ....
}

Thank you for your reply!

That if ((In&1<<2) != 0) and (!W) = (W == 0) simplification really helped. Any similar ones that I might come across on exam?


Let me quickly comment on the code and please correct me where I might be wrong. Also, how do we get the last Out value?

The value of Out before the second if statement is 10.
Out &= ~(1 << 1)
moving 1 to the left gets us 0b10
~ and we get 0b01
1010 &= 01 ....is 0?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 uint8_t In = 5, Out = 8, W = 85;

  if (In&1<<2) {   //Because (In&1<<2) isn't 0, the values inside the if statements get changed.
     W=In;        
     Out ^= 2;
     } 
  In ^= W;
  if (!W) {   //If W would be 0 the if statement would be read, but because it isn't it jumps to "else".
     W=Out;
     Out |= 1<<1;
     }
     else 
  Out &= ~(1 << 1);    //Why does this line change the value of Out from 10 to 8?
  W ^= W;      
If this is for an exam, the pedantically correct answer would be:

!W is interpreted as !bool(W)

ie. W (the operand of the built-in logical operator ! is contextually converted to bool,
and the bool result of that conversion is then negated.

Standard boolean conversions:
A prvalue of arithmetic, unscoped enumeration, pointer, or pointer-to-member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.
https://eel.is/c++draft/conv.bool#1
JLBorges wrote:
the pedantically correct answer would be

Point taken, I was simply "winging it" without any coffee. :)

And if you weren't addressing my comment directly I still understand the point being made, m'ok?
ok got it.

Any ideas why the value of Out has to be 8 at the end?
             Out == 00001010  (10)
          1 << 1 == 00000010  (2)
       ~(1 << 1) == 11111101  (253)
 Out & ~(1 << 1) == 00001000  (8)


http://coliru.stacked-crooked.com/a/d32a3e4c7be98823
Much appreciated, thank you very much!
Topic archived. No new replies allowed.