Pregunta Explicación de los operadores de bit JavaScript en esta función.


Tengo este bloque de código:

EventBus.on('pfio.inputs.changed', function(state, prev_state) {
    var changed = prev_state ^ state;
    for (var pin = 0; pin < 8; pin++) {
        if ((changed & (1 << pin)) === (1 << pin)) {
            EventBus.emit('pfio.input.changed', pin, ((state & (1 << pin)) === (1 << pin)));
        }
    }
});

estado será un número de 8 bits: 00000000
estado anterior será un número de 8 bits: 11001110

Estos números se refieren a estados de conmutación, por lo que el primero en estado significa que el pin 1 está desactivado. En estado anterior el primer 1 significa que el interruptor 8 está encendido.

Entiendo la simple ejecución del código, son estos bits que no puedo entender:

(changed & (1 << pin)) === (1 << pin))

((state & (1 << pin)) === (1 << pin)));

prev_state ^ state;

¡Cualquier explicación sobre este asunto sería de gran ayuda!


5
2018-02-14 15:13


origen


Respuestas:


^ es el XOR operador: dado dos números, "alinea" sus lugares y cambia el lugar solo si solo uno De los dos números tiene ese lugar:

// All of these are binary
111 ^ 111 === 000
110 ^ 111 === 001
110 ^ 110 === 000

Esto significa que changed será un número con solo los lugares establecidos que se establecen en prev_state  o  state pero no ambos.

Como para << ese es el operador del desplazamiento a la izquierda: de hecho está elevando el número del lado izquierdo con la potencia de dos que es el número del lado derecho:

// Decimal numbers on the left, binary numbers on the right
1 << 1 === 10    // 2
1 << 2 === 100   // 4 
1 << 3 === 1000  // 8

// You can use any number on the LHS
2 << 1 === 100   // 4
3 << 2 === 1100  // 12
// Remember, 3 in decimal is equal to 11 in binary

Finalmente, & es el operador binario y devuelve un número donde el lugar solo está configurado si ambos los números tienen 1 en ese lugar:

// Both sides binary
1 & 1 === 1
11 & 10 === 10
010 & 100 === 0

Entonces, en su ciclo, los primeros 8 bits de los cambios se verifican para ver si alguno de ellos está configurado; si alguno de ellos está configurado, algo cambió y se desencadena un evento. Puede ser más fácil ver si lo descomponemos en dos pasos:

// All numbers in binary save for 8 ;-)
prev_state = 11111111;
state = 11011111;
changed = 00100000;

Iteración # 1:

mask = 1 << 0                   // 0
changeAtPower = changed & mask  // 0
// 0            0         0
mask === changedAtPower         // false

Iteración # 2:

mask = 1 << 1                   // 10
changeAtPower = changed & mask  // 0
// 00           00        01
mask === changedAtPower         // false

Saltarse las iteraciones n. ° 3 al n. ° 5, que se ven todas iguales, echemos un vistazo al n. ° 6:

mask = 1 << 5                    // 100000
changedAtPower = changed & mask  // 100000
// 100000        100000    100000
mask === changedAtPower         // true 
// Event triggered

Y luego continúa para las iteraciones restantes (# 7 y # 8) y como nada ha cambiado, no se apagan más eventos.


7
2018-02-14 15:29



prev_state ^ state

hace una máscara de bits que es 1 donde sea un poco en el prev_state no está de acuerdo con el bit correspondiente en state, ver xor.

(changed & (1 << pin)) === (1 << pin))

prueba si el bit con índice pin está configurado, lo que significaría que ese pin en la posición ha cambiado.

((state & (1 << pin)) === (1 << pin)))

también prueba si el bit con índice pin está configurado, lo que en este caso significa que el pin en esa posición ahora es 1 / set / true


1
2018-02-14 15:28