本文中 a 的取值范围是 [-2147483648, 2147483647]b 为非负整数

是因为对于位移动运算 a << ba >> b,如果右操作数 b >= 32,则只会取 b最低五个二进制位进行运算(相当于 b % 32)。

所以整数左移/右移32位,相当于左移/右移0位,仍等于自身:

1
2
 3 >> 32;  //  3
-6 << 32; // -6

非整数在左移/右移前会先舍去小数点后的部分(注意:不是Math.floor!详见JS的向下取整确切来讲,是 Math.trunc)再进行运算,因此:

1
2
3
a >> 32 === Math.trunc(a);
// 同理
a >> 32 === ~~a;

在其他语言中的测试:

p = 180q = -66(分别为大于0和小于0的随机整数)

  • Python 2:

    1
    2
    3
    4
    p >> 32  # 0, sign(p)
    q >> 32 # -1, sign(q)
    p << 32 # 773094113280, Big Integer
    q << 32 # -283467841536, Big Integer
  • Python 3: The same as Python 2

  • php:

    1
    2
    3
    4
    echo $p >> 32;  // 0
    echo $q >> 32; // -1
    echo $p << 32; // 773094113280, var_dump() returns int
    echo $q << 32; // -283467841536, ditto
  • Julia:

    1
    2
    3
    4
    p >> 32  # 0, sign(p)
    q >> 32 # -1, sign(q)
    p << 32 # 773094113280, typeof() returns Int64
    q << 32 # -283467841536
  • C/C++: There's no need to test

  • perl:

    1
    2
    3
    4
    print(p >> 32);  # 0
    print(q >> 32); # 4294967295
    print(p << 32); # 773094113280
    print(q << 32); # 18446743790241710080, I just have no idea about why. Not familiar with perl
  • ruby:

    1
    2
    3
    4
    print(p >> 32);  # 0
    print(q >> 32); # -1
    print(p << 32); # 773094113280
    print(q << 32); # -283467841536
  • Java: I have no java development env on my Mac

综上,似乎只有 JS 有这种令人迷惑的”取最低五位“行为。(不过 Perl 的 -66 << 32 也挺迷惑的)

来源:https://blog.jiejiss.com/