Why do certain situations require the use of “bitwise” operators instead of “logical” / “equality” operators?

The other day, I tried to code a little C ++ programming using the SDL multimedia library, and I ran into this little problem, which I eventually resolved through trial and error. The problem is that I understand what I did to solve the problem, but I do not really understand the essence of the problem!

The problem was handling keyboard events in the SDL. The code for processing a single keystroke to exit the program is simple and simple. [eventQueue - structure SDL_Event]

//checks for keypress events.. if ( eventQueue.type == SDL_KEYDOWN ) { //note: uses the boolean logical '==' equals operator.. if ( eventQueue.key.keysym.sym == SDLK_ESCAPE ) { running = false; } } 

In the above code, just pressing the ESCAPE key at its ends completes the main loop and forces the program to clear and close ...

However ... The code needed to handle keystrokes that use modifier keys (shift / alt / ctrl) does not work correctly with the '==' operator. It took me a long time to figure out that I needed to use the bitwise AND operator instead of the equality operator (logical?).

 //checks for keypress events.. if ( eventQueue.type == SDL_KEYDOWN ) { //note: requires the use of the bitwise AND operator.. if (( eventQueue.key.keysym.mod & KMOD_ALT ) && (eventQueue.key.keysym.sym == SDLK_F4 )) { running = false; } } 

My confusion here arises from the fact that when using the "keysym.sym" member, the boolean operator "==" works fine, however, when using the "keysym.mod" member, it was necessary to use the & bitwise AND operator.

Now, if I were to guess, I would say that it has something to do with the fact that "keysym.sym" should only process one numeric value, which is one key on the keyboard, and "keysym". mod 'has to deal with various key combinations shift, ctrl and alt ...?

To summarize my question: Why is this so? Do I need to learn at all, except trial and error, do I need to compare some of the data with bitwise or logical / equality operators? Why does "keysym.sym == SDLK_F4" work fine, but "keysym.mod == KMOD_ALT" doesn't? Why does an operation involving decimal numbers have a different result than an operation that compares the values ​​of bits? Are there also situations where the operation of logical operations and bitwise operations will not work?

+3
source share
3 answers

Bitwise AND is somewhat special. == checks equality, but the bitwise AND operator allows you to work with individual bits of a number.

Imagine your event was defined as a list of keys:

 event = ['a', 'shift', 'ctrl'] 

Then you can check if a particular modifier is easily part of the event:

 if 'shift' in event: # ... 

The bitwise AND value is similar to the in statement. You can define your event as a binary number like this:

 event = 00010010 

Now that you are doing bitwise AND, you can easily check if a specific modifier has been applied to the event, since the modifiers are also represented as binary numbers:

  00010001 # event (18) & 00010000 # shift key (8) ---------- 00010000 # you get a non-zero answer, so the shift key is in the event ---------- 00010001 # event (18) & 00001000 # "z" key (4) ---------- 00000000 # you get zero because the "z" key wasn't a part of the event ---------- 

You can build an event like this using a bitwise OR:

  00000001 # shift key (1) | 10100000 # "a" key (160) ---------- 10100001 # resulting event (161) ---------- 

Wikipedia describes bitwise operations pretty well:

A bitwise operation works with one or more bit patterns or binary numbers at the level of their individual bits. This is a quick, primitive action directly supported by the processor and is used to manage values ​​for comparisons and calculations. On simple inexpensive processors, as a rule, bitwise operations are significantly faster than division, several times faster than multiplication, and sometimes much faster than addition. While modern processors typically perform addition and multiplication as fast as bitwise operations due to their longer pipelines and other architectural design options, bitwise operations typically use less power / performance due to limited resource utilization.

Basically, bitwise operators can effectively work with information stored in bits of an integer.

+5
source

What have you done here

 eventQueue.key.keysym.mod & KMOD_ALT 

It is not a comparison operation, it is a masking operation. The comparison operation is implicit in C and C ++: an expression that evaluates to zero means false, all non-zero values ​​mean true. When used in a logical expression like yours, this is a shorthand for

 (eventQueue.key.keysym.mod & KMOD_ALT) != 0 

Now for bit operations: some values ​​represent bit combinations of two or more values. For example, keysym.sym represents a combination of a bitmap for ALT (which itself is a combination of left and right ALT) and any other key that can be pressed simultaneously. To separate one value from a combination, the bit masking method is used: a value that has units in the bits of interest and zeros in all other bits (this is KMOD_ALT ), has the value AND (value) (in your case, it keysym.sym ), producing the keysym.sym bit in bits denoted by 1 KMOD_ALT .

The end result is that eventQueue.key.keysym.mod & KMOD_ALT will be nonzero only if ALT is pressed.

+3
source

Disclaimer: I know almost nothing about SDL. I answer here mainly from guesswork.

There are several keys on the keyboard that are expected to generate a key event no matter how many other keys are pressed. Modification keys, such as Shift , Alt , Ctrl , are such keys (not sure if there are any more), and the keyboard manufacturer must make sure that they can be pressed at the same time. The remaining keys are normal keys and may or may not generate a key event when pressed simultaneously, depending on the layout of each keyboard.

When a normal key is pressed, a key event is a trigger (not sure if a modifier key press will trigger an event). The normal key is in sym and whether any modifier key will be pressed while pressing a regular key in mod . I am sure that by implementation, a specific bit in mod used to determine if any modifier key is pressed or not. To check if a bit is enabled or not, you need a wise & bit with a constant that determines which bit is used to indicate whether the modifier key is pressed or not.

+1
source

Source: https://habr.com/ru/post/1479991/


All Articles