javascript - JS bitwise shift operator '>>' not returning the correct result - Stack Overflow

I found this weird problem in JS. I have some native bindings to a board game api that uses bitboards f

I found this weird problem in JS. I have some native bindings to a board game api that uses bitboards for representing the game state. I am trying to manipulate these bitboards in JS to display the result in a web-based GUI (using electron).

The 1s in the bitboard represent the position of the pieces. Here is an example:

const bitboard = 0b100000010000000000000000000000000000;

However, when I do bitboard >>= 1;, the value magically bees 0b1000000000000000000000000000.

Runnable example:

const bitboard = 0b100000010000000000000000000000000000; // 0b is binary literal
console.log(bitboard.toString(2));
console.log((bitboard >> 1).toString(2)); // .toString(2) prints the number in binary

I found this weird problem in JS. I have some native bindings to a board game api that uses bitboards for representing the game state. I am trying to manipulate these bitboards in JS to display the result in a web-based GUI (using electron).

The 1s in the bitboard represent the position of the pieces. Here is an example:

const bitboard = 0b100000010000000000000000000000000000;

However, when I do bitboard >>= 1;, the value magically bees 0b1000000000000000000000000000.

Runnable example:

const bitboard = 0b100000010000000000000000000000000000; // 0b is binary literal
console.log(bitboard.toString(2));
console.log((bitboard >> 1).toString(2)); // .toString(2) prints the number in binary

Edit: The same code works in Rust which is the language that I am using on the native side.

Share Improve this question edited Sep 2, 2020 at 2:36 Phil 165k25 gold badges262 silver badges267 bronze badges asked Sep 2, 2020 at 2:32 LukeLuke 6156 silver badges21 bronze badges 5
  • 2 JavaScript's "numbers" are all floating-point internally so you can get a lot of weirdness with values like this that are > ~2^28. You may want >>> instead which is the "zero-fill right-shift operator". – tadman Commented Sep 2, 2020 at 2:36
  • Tip: Just delete the last character of a string representation. – tadman Commented Sep 2, 2020 at 2:37
  • 1 bitwise operators work with 32bit values - you have 36bits – Jaromanda X Commented Sep 2, 2020 at 2:45
  • @JaromandaX With testing I found the break-point to be 29 bits, so that approximation is close. This is specifically for bit-shifting, not general-purpose numbers. – tadman Commented Sep 2, 2020 at 2:48
  • @JaromandaX Misread the number. – tadman Commented Sep 2, 2020 at 2:55
Add a ment  | 

2 Answers 2

Reset to default 6

There's probably a duplicate floating around somewhere but the solution here is to use BigInt

BigInt is a built-in object that provides a way to represent whole numbers larger than 253 - 1, which is the largest number JavaScript can reliably represent with the Number primitive and represented by the Number.MAX_SAFE_INTEGER constant. BigInt can be used for arbitrarily large integers.

You just need to make sure that both operands for the right-shift operator are the same type.

const bitboard = BigInt("0b100000010000000000000000000000000000")
console.log(bitboard.toString(2))
console.log((bitboard >> 1n).toString(2)) // note "1n"

There are limits on what sorts of numerical values JavaScript can bit-shift. Using Node I found the cut-off right here at 32 bits:

0b10000000000000000000000000000000 >>> 1 // 32 bits
# => 1073741824
0b100000000000000000000000000000000 >>> 1 // 33 bits
# => 0

Where it just breaks down. Your binary value is over that threshold so you can't shift it using JavaScript's default representation.

You can do this with BigInt:

BigInt('0b100000010000000000000000000000000000') >> BigInt(1)
# => 17314086912n

Where that is the correct value.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745476367a4629365.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信