Что на самом деле делает этот конкретный оператор IF в C (это тоже работает)? - PullRequest
0 голосов
/ 18 апреля 2019

Я наткнулся на некоторый пример кода, который отлично работает для моего приложения, но я не уверен, что на самом деле происходит в операторе IF.

unsigned int steps;
uint16_t selected_steps; 

for (int j = 16; j>=0; j--)
{
    if (((selected_steps^(1 << step_number))>>j) & 0x1) {
          some code...
      } else {
          other code...
      }

Я знаю назначение кода, оно состоит в том, чтобы проверить, равен ли бит в selected_steps [j] XOR step_number 1 или 0. Selected_steps [j] равно 0 или 1. Номер шага принимает значения в диапазоне от 0 до 15.

Но я не понимаю, что на самом деле делается, делая

(1 << step_number)

и что тогда делается,

selected_steps^(1 << step_number)) >> j

Я полагаю, что вышеприведенный оператор выводит 1 или 0, поскольку он проверяет 0x1?

Ответы [ 2 ]

4 голосов
/ 18 апреля 2019

Рассмотрим, что произойдет, если step_number отличается от j.Затем: ((selected_steps^(1 << step_number))>>j) & 0x1 делает это:

  • XOR с 1 << step_number изменяет некоторый бит selected_steps, отличный от бита j.Но, как мы увидим, нас это не волнует.
  • Затем >>j перемещает бит j в положение 0.
  • Затем & 0x1 выделяет этот бит.
  • Результат равен true, если бит j в selected_steps равен true.

С другой стороны, если step_number равно j, то XOR изменяет бит jи результат равен true, если бит j в selected_steps равен false.

Таким образом, выражение эквивалентно (step_number == j) != (selected_steps >> j & 1).

1 голос
/ 18 апреля 2019

Разбейте его на шаги.

uint16_t mask = 1 << step_number ; // A bit mask with single 
                                   // bit `step_number` set.

uint16_t xor_step = selected_steps ^ mask ; // Toggle bit `step_number`.

uint16_t bit_j = (xor_step >> j)  & 0x1 ;   // Get the single bit `j`

if( bit_j  ) ... // If bit j is not zero.

Так, например, когда:

selected_steps == 0x5AA5 (binary:0101101010100101) 
j == 5
step_number == 10

тогда:

mask = 1 << 10 (Binary: 0000001000000000)

selected_steps: 0101101010100101
          mask: 0000001000000000
         -----------------------
           XOR: 0101100010100101 == xor_step
                      ^
                      |_ Toggled bit

                         ,- Bit 5 (j)
                         V      
     xor_step: 0101100010100101
shift right 5: >>>>>01011000101
                              ^
                              |_ Bit 5 moved to LSB

               0000001011000101         
        AND 1: 0000000000000001 == bit j

Таким образом, вы получите бит j из selected_steps после переключения бит step_number.Если j != step_number, то переключение не влияет на результат.

Как это достигает цели вашего приложения, невозможно сказать, учитывая агрессивное исключение вашего кода.Предположительно в действительности selected_steps и step_number не являются инвариантными к циклам (и steps не используются, и selected_steps фактически инициализируются в этом отношении)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...