2

JavaScript integers can go up to 2^53, yet all bit operations only go up to 2^32. Sometimes I need to perform bit operations on numbers between 2^32 and 2^53, so I have to write substitute functions for all the bit operations:

Here's what I have so far:

function lshift(num, bits) {
  return num * Math.pow(2, bits);
}

function rshift(num, bits) {
  return Math.floor(num / Math.pow(2, bits));
}

Is this the best way to implement the shift functions?

I now need to implement & and |. In my code I often have to & by 127 and 128 but I'm not sure of how to do so.

I don't need ~ or ^, but they could be included in the answer for completeness I guess.

Chron Bag
  • 587
  • 4
  • 17
  • This might be interesting for you: https://github.com/peterolson/BigInteger.js – basilikum Jul 21 '16 at 18:41
  • 1
    Here's a question about the bitwise shift http://stackoverflow.com/a/337572/5743988, the answer uses your method. This question http://stackoverflow.com/q/3637702/5743988 is about bitwise AND. I haven't seen any questions for `|` in 64 bit – 4castle Jul 21 '16 at 18:44

1 Answers1

2

One general remark: It seems to make sense to keep all numbers positive to avoid issues with 1-complement.

For the lshift function, I am not sure if it would pay off to do some checks if the shift won't overflow 32 bit, and use the regular shift operation in this case: It might reduce complex operations, but it will also add checks and branching...

function and(a, b) {
  var low = a & b & 0x7fffffff;
  if (a <= 0x7fffffff || b <= 0x7fffffff) {
    return low;
  }
  var hi = rshift(a, 31) & rshift(b, 31);
  return low + lshift(hi, 31);
}

function or(a, b) {
  var low = (a | b) & 0x7fffffff;
  if (a <= 0x7fffffff && b <= 0x7fffffff) {
    return low;
  }
  var hi = rshift(a, 31) | rshift(b, 31);
  return low + lshift(hi, 31);
}

function xor(a, b) {
  var low = (a ^ b) & 0x7fffffff;
  if (a <= 0x7fffffff && b <= 0x7fffffff) {
    return low;
  }
  var hi = rshift(a, 31) ^ rshift(b, 31);
  return low + lshift(hi, 31);
}

function rshift(num, bits) {
  return num <= 0x7fffffff ? num >> bits : 
      Math.floor(num / Math.pow(2, bits));
}

Edit: Fixed a bug in or, added xor

Stefan Haustein
  • 18,427
  • 3
  • 36
  • 51