Why do Ruby and JavaScript bitwise operators yield different results with the same operands?
For example:
256 >> -4 # => 4096 (Ruby)
256 >> -4 # => 0 (Javascript)
Any tips/pointers are appreciated.
Why do Ruby and JavaScript bitwise operators yield different results with the same operands?
For example:
256 >> -4 # => 4096 (Ruby)
256 >> -4 # => 0 (Javascript)
Any tips/pointers are appreciated.
For the Ruby version, it looks like 256 >> -4 is equivalent to 256 << 4, so the negative operand essentially just switches the direction of the shift.
From looking at the ECMAScript specification for the right-shift operator, in JavaScript, the operand is converted to an unsigned 32-bit integer before the shift, so the -4 becomes 4294967292. After this conversion the 5 least-significant bits are used for the shift, in other words we would end up shifting by 4294967292 & 0x1f bits (which comes out to 28). It probably shouldn't surprise you at all to see that 256 >> 28 gives 0.
For convenience, here is the text from the spec (steps 6 and 7 are most relevant to your confusion here):
The Signed Right Shift Operator (
>>)Performs a sign-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:
- Let
lrefbe the result of evaluating ShiftExpression.- Let
lvalbeGetValue(lref).- Let
rrefbe the result of evaluating AdditiveExpression.- Let
rvalbeGetValue(rref).- Let
lnumbeToInt32(lval).- Let
rnumbeToUint32(rval).- Let
shiftCountbe the result of masking out all but the least significant 5 bits ofrnum, that is, computernum & 0x1F.- Return the result of performing a sign-extending right shift of
lnumbyshiftCountbits. The most significant bit is propagated. The result is a signed 32-bit integer.
As a side note, if you want to play around with this by converting a value to an unsigned 32-bit integer you can use val >>> 0 as seen in touint32.js from V8 JavaScript Engine.