2011-08-09 30 views
5

Tengo un pedazo de código Javascript estoy tratando de entender¿Qué significa ">>" y "<<" en Javascript?

// read big-endian (network byte order) 32-bit float 
readFloat32 = function(data, offset) { 
    var b1 = data.charCodeAt(offset) & 0xFF, 
     b2 = data.charCodeAt(offset+1) & 0xFF, 
     b3 = data.charCodeAt(offset+2) & 0xFF, 
     b4 = data.charCodeAt(offset+3) & 0xFF; 
    var sign = 1 - (2*(b1 >> 7));  //<--- here it is and 2 lines below 
    var exp = (((b1 << 1) & 0xff) | (b2 >> 7)) - 127; 
    var sig = ((b2 & 0x7f) << 16) | (b3 << 8) | b4; 
    if (sig == 0 && exp == -127) 
     return 0.0; 
    return sign * (1 + sig * Math.pow(2, -23)) * Math.pow(2, exp); 
} 

¿Qué significa ">>" significa? Es un tipo especial de booleano (como '<' o '>')

Respuesta

7

Estos son los operadores shift right (with sign) y shift left.

Básicamente, estos operadores son utilizados para manipular valores en el nivel BIT.
Se utilizan generalmente junto con los operadores & (AND bit a bit) y | (OR bit a bit) y en asociación con masks valores como 0x7F y valores inmediatos similares encontraron el fragmento de la pregunta.
El fragmento en cuestión utiliza estos operadores para "analizar" los tres componentes de un valor flotante de 32 bits (signo, exponente y fracción).

Por ejemplo, en fragmento de la pregunta:
1 - (2*(b1 >> 7)) produce la número entero valor 1 o -1 dependiendo de si el bit 7 (el octavo bit de la derecha) en la variable b1 es cero o uno, respectivamente.
Este idioma se puede explicar de la siguiente manera.

  • al comienzo, b1, expresada en bits es 0000000000000000abcdefgh
    nota cómo todos los bits de la izquierda son ceros, esto viene de la asignacion
    b1 = data.charCodeAt(offset) & 0xFF unas líneas más arriba, que esencialmente cero-ed toda la bits en b1 excepto para el rightmot 8 bits (máscara 0xFF).
    a, b, c ... hasta h representan valores booleanos desconocidos 0 o 1.
    Estamos interesados ​​en probar el valor de a.
  • b1 >> 7 turnos este valor a la derecha por 7 bits, dejando
    b1 como 00000000000000000000000a que, lee como un entero tendrá valor 1 o 0
  • este valor 1 o 0 número entero se multiplica por 2
    entonces es 2 o 0, respectivamente.
  • este valor se resta entonces de 1, dejando ya sea -1 o 1.

Aunque es útil para ilustrar la forma en que el trabajo a los operadores de bits, el lenguaje anterior podría ser sustituido por algo que pone a prueba el bit 7 más directamente y asigna la variable de signo más explícitamente. Además, este enfoque no requiere el enmascaramiento inicial de los bits más a la izquierda en b1:

var sign 
if (b1 & 0x80) // test bit 7 (0x80 is [00000000]10000000) 
    sign = -1; 
else 
    sign = 1; 
0

desplazamiento a la izquierda y cambiar los operadores adecuados. Si tiene un número, desplazará sus bits hacia la izquierda o hacia la derecha.

0

Es el operador bitshifting. Vea here para más detalles.

0

Right y Left y operadores de desplazamiento.

1

turno a entre b bits a la izquierda (relleno con ceros)

a << b 

cambio de una de b bits a la derecha (copiar el bit de signo)

a >> b 
0

Son operadores BitShift. Los números en la computadora están representados en binario. Desplazar a la izquierda equivale a multiplicar por 2 y desplazar a la derecha es equivalente a dividir por 2.

Por ejemplo, el número 8 es 1000 en binario. Shift dejó << por 3 produciría 1000000 que es 64. Shift derecha por 2 sería dió 10 que es 2.

1

De http://ecma262-5.com/ELS5_HTML.htm

11.7 operadores de desplazamiento a nivel de bit

ShiftExpression: AdditiveExpression ShiftExpression < < AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression

11.7.1 El operador de desplazamiento a la izquierda (< <) realiza una función dada operación de desplazamiento en el operando de la izquierda en la cantidad especificada por el operando de la derecha. El ShiftExpression producción: ShiftExpression < < AdditiveExpression se evalúa de la siguiente manera:

Let lref be the result of evaluating ShiftExpression. 
Let lval be GetValue(lref). 
Let rref be the result of evaluating AdditiveExpression. 
Let rval be GetValue(rref). 
Let lnum be ToInt32(lval). 
Let rnum be ToUint32(rval). 
Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F. 
Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer. 

11.7.2 El operador de desplazamiento a la derecha Firmado (>>) realiza una operación de desplazamiento a la derecha en modo bit de inicio de sesión de llenado en el operando de la izquierda por la cantidad especificado por el operando correcto.

El ShiftExpression producción: ShiftExpression >> AdditiveExpression se evalúa de la siguiente manera:

Let lref be the result of evaluating ShiftExpression. 
Let lval be GetValue(lref). 
Let rref be the result of evaluating AdditiveExpression. 
Let rval be GetValue(rref). 
Let lnum be ToInt32(lval). 
Let rnum be ToUint32(rval). 
Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F. 
Return the result of performing a sign-extending right shift of lnum by shiftCount bits. The most significant bit is propagated. The result is a signed 32-bit integer. 
+1

No es que éstos convertir los números en Int32 - mientras que casi todo lo demás en Javascript funciona en dobles de 64 bits. –