2

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

in javascript:

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

produces 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

d_a_n
  • 317
  • 7
  • 16

1 Answers1

3

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.

Community
  • 1
  • 1
ssube
  • 47,010
  • 7
  • 103
  • 140
  • thanks @ssube, it was looking like a js limitation, any ideas on replicating this in Ruby? – d_a_n Jun 21 '16 at 20:31
  • @d_a_n I've never heard of anybody wanting to force overflows, but it's pretty easy math. Editing it in. – ssube Jun 21 '16 at 20:56