开发者

Javascript bit shift- number wraps?

I am converting some Java code to Javascript to run on node.js, and I ran into something peculiar with bit shifting.

The original Java used a long and logical bit shifting, so I've replicated that in Javascript (I get the same results with an arithmetic shift):

var num = 3382;

num >>> 0 & 0xFF; // 54, as expected
num >>> 8 & 0xFF; // 13, as expected
num >>> 16 & 0xFF; // 0, as expected
num >>> 24 & 0xFF; // 0, as expected
num >>> 32 & 0xFF; // 54??
num >>> 40 & 0xFF; // 13??

I get the same results on node, FF 4 and Chrome 12.

It seems that Javascript is wrapping the bits in the integer when it runs out of bits. Javascript, AFAIK, allows up to 32-bit numbers in the background, but this shouldn't be an issue.

Binary Representation

This is what I think is happening:

0开发者_开发百科-shift: 00000000000000000000110100110110

8-shift: 00110110000000000000000000001101

16-shift: 00001101001101100000000000000000

24-shift: 00000000000011010011011000000000

32-shift: 00000000000000000000110100110110

Sanity Check

I wrote a little test in C to make sure I wasn't going insane (note, there are compile warnings, but that's expected):

#include <stdio.h>

int main() {
    printf("Bit shift tests:\n");
    printf("3382 >> 0 & 0xFF: %d\n", 3382 >> 0 & 0xFF);
    printf("3382 >> 8 & 0xFF: %d\n", 3382 >> 8 & 0xFF);
    printf("3382 >> 16 & 0xFF: %d\n", 3382 >> 16 & 0xFF);
    printf("3382 >> 24 & 0xFF: %d\n", 3382 >> 24 & 0xFF);
    printf("3382 >> 32 & 0xFF: %d\n", 3382 >> 32 & 0xFF);
    printf("3382 >> 48 & 0xFF: %d\n", 3382 >> 48 & 0xFF);
    printf("3382 >> 56 & 0xFF: %d\n", 3382 >> 56 & 0xFF);
    printf("3382 >> 64 & 0xFF: %d\n", 3382 >> 64 & 0xFF);
}

Note

I only care about 32-bit numbers. The Java code used 64 bit numbers, but the numbers represent file sizes and I won't be using big files (all under 50 megs or so).

Question

I have read the wikipedia articles about arithmetic and logical bit shifts, but it doesn't seem that Javascript is following the rules.

Could someone explain to me what's going on?


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

11.7.3 The Unsigned Right Shift Operator ( >>> )

Performs a zero-filling bitwise right shift operation on the left operand by the amount specified by the right operand.

The production ShiftExpression : ShiftExpression >>> AdditiveExpression is evaluated as follows:

1 Let lref be the result of evaluating ShiftExpression.

2 Let lval be GetValue(lref).

3 Let rref be the result of evaluating AdditiveExpression.

4 Let rval be GetValue(rref).

5 Let lnum be ToUint32(lval).

6 Let rnum be ToUint32(rval).

7 Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.

8 Return the result of performing a zero-filling right shift of lnum by shiftCount bits. Vacated bits are filled with zero. The result is an unsigned 32-bit integer.

Note step 7, the shift count is truncated to 5 bits, so 32 becomes 0 and 40 becomes 8 and the values you are getting conform to the specification.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜