简体   繁体   中英

difference between javascript and ruby integers (using left shift bitwise operator)

I'm trying to replicate a javascript check digit function in Ruby. The results are differing and it looks as though it is related to the size of the integer.

in Ruby:

puts "#{1421974191} | #{(1421974191 << 5)}"

produces 1421974191 | 45503174112 1421974191 | 45503174112

in javascript:

alert(1421974191 + ' | ' + (1421974191 << 5))

produces 1421974191 | -1741466144 1421974191 | -1741466144

I'd be grateful for any advice on why this is happening, and how I can replicate the javascript in Ruby.

Thanks in advance

Dan

JS' bitwise operators are limited to 32-bit values, so you're getting an overflow. From the MDN page :

The operands of all bitwise operators are converted to signed 32-bit integers in two's complement format.

Modern JS engines will actually prefer the two's complement format and bail out to a 64-bit floating point value if you push them, but the bitwise operators force a conversion back to 32-bit integers before doing anything.

The spec is very clear about this. From section 12.8.3.1 :

  1. Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer.

To mimic integer overflow in Ruby (or any language with large numbers), you can use the formula (taken from this Python answer ):

((n + 2147483647) % 4294967294) - 2147483647

As the answer notes, this only works with left-shifting, not division or right-shifting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM