Operaciones binarias

El ordenador, internamente, trata cualquier tipo de datos como una cadena binaria ( ceros y unos). Así los números se representan en sistema binario de numeración mientras que los caracteres se convierten a código ASCII, que son números que se almacenan por tanto codificados en binario.

JavaScript ofrece los operadores típicos para trabajar con estas cadenas a nivel de bit (cada uno de los ceros o unos de las cadenas binarias).

Para comprender como funcionan estos operadores es bueno tener conocimientos previos sobre codificación binaria. Auqnue así apra empezar puedes considerar que estos operadores trabajan con literales que solo tienen 0 y 1.

Y para terminar de enteder un poco ten en cuenta que estos operadores representa los números como una cadena de 32 bits, si empieza por 0 es positivo y si empieza por 1 es negativo (almacenamiento complemento a 2).

Complementación ~
Complementa, o niega, una cadena binaria conviertiendo los 1 en 0 y los 0 en 1.
Por ejemplo el número 38 escrito en sistema binario es 00100110 si le aplicamos este operador se convierte en 11011001, o sea el -39 (JavaScript usa codificación en complemento a 2 para los números negativos).
Desplazamiento izquierda <<
Desplaza los bits a la izquierda los lugares que se le indique rellenando con ceros por la derecha y desechando los bits de mayor peso, esto equivale a multiplicar por potencias de 2. Por ejemplo si al 00011010 (26) lo desplazamos 2 a la izquierda tendremos el 01101000 (104). Como ultiplicar 26 po 4 ( 2 elevado a 2).

var num = 26, res;

res = num << 2;        

/* num contendrá 104 */

Desplazamiento derecha >>
Desplaza los bits a la derecha los lugares que se le indique rellenando con ceros por la izquierda y desechando los bits de menor peso, esto equivale a una división entera por potencias de 2. Por ejemplo si al 00011010 (26) lo desplazamos 2 a la derecha tendremos el 00000110 (6). Es dividir 26 entre 4, cuyo cociente entero es 6.

var num = 26, res;

res = num >> 2; /* num contendrá 6 */

AND lógico binario &
Realiza un AND lógico bit a bit entre dos valores. El AND lógico da como resultado 1 sólo si ambos bits son 1, si ambos son verdadero. Por ejemplo
                              0 1 1 0 1 1 0 1 (109)
                    AND 0 0 1 0 0 1 1 0 (38)
resultado:             0 0 1 0 0 1 0 0 (36)

var op1 = 109, op2 = 38, res;

res = op1 & op2;      /*res contiene 36 */

OR lógico binario |
Realiza un OR lógico bit a bit entre dos valores. El OR lógico da como resultado 0 sólo si ambos bits son 0. Por ejemplo
                              0 0 1 1 1 0 1 0    (58)
                        OR  0 1 0 1 0 0 1 0     (82)
resultado:              0 1 1 1 1 0 1 0    (122) En el ejemplo podemos ver la sintaxis del operador

var op1 = 58, op2 = 82, res;

res = op1 | op2;                    /*res contiene 122 */

XOR lógico binario ^
Realiza un XOR lógico bit a bit entre dos valores. El XOR lógico da como resultado 1 si uno sólo de los bits es 1. Por ejemplo
                               0 0 1 1 1 0 1 0    (58)
                        OR  0 1 0 1 0 0 1 0     (82)
resultado:               0 0 1 0 1 0 0 0    (40)
En el ejemplo podemos ver la sintaxis del operador

var op1 = 109, op2 = 38, res;

res = op1 ^ op2;                 /*res contiene 40*/

Ejemplos

Este tipo de operaciones no parecen muy habituales, pero tienen todo el sentido cuando trabajas con datos binarios. Por ejemplo manipulando una imagen o para operciones algebráicos.

En ocasiones estos operadores permiten optimizar el código. Por ejemplo ¿como clacularías la parte entera de un número decimal? Con una función round del objeto Math (Math.round() ), pero también puedes usar los operadores OR o XOR sobre 0

var decimal = 12.654;

var entero;

console.log ( decimal | 0 )

Otro ejemplo curioso, para saber si un número es par en ugar del operador % puedes usar operadores lógicos, será par si al despalzarlo a derecha e izquierda un lugar no cambia

var numero = 12;

var par;

par = (numero>>1)<<1

console.log( "Es par " + par)

Advertencia: el uso de decimales en Javascript no es nada fiable debido al sistema de representación interno. Es necesario utilizar código extra para lograr salvar esos errores.