Toc
  1. 一、>> 和 >>> 区别
  2. 二、移位0有什么意义
  3. 三、Uint32类型是如何转换的
  4. 四、总结
Toc
0 results found
bbcfive
js中表达式 >>> 0 浅析

本文转自:《js中表达式 >>> 0 浅析》

一、>> 和 >>> 区别

>>>是无符号右移,>>是有符号移位

>>有符号移位:该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧

1
2
3
4
-9 >> 2
11111111111111111111111111110111 // -9
->
11111111111111111111111111111101 // -3

>>>无符号移位:该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(即便右移 0 个比特,结果也是非负的。)

1
2
3
4
9 >>> 2
00000000000000000000000000001001 // 9
->
00000000000000000000000000000010 // 2

根据文档说明即使移动0位也可以将一个负数变成正数,甚至也可以将一个小数变成整数,将未定义的值转换为0,那到底移动0位是什么意思。

二、移位0有什么意义

查过一些资料,其中stackoverflow里面有一个高票回答,里面有这么一句话

It doesn’t just convert non-Numbers to Number, it converts them to Numbers that can be expressed as 32-bit unsigned ints.

原来移位操作符在移位前做了两种转换,第一将不是number类型的数据转换为number,第二将number转换为无符号的32bit数据,也就是Uint32类型。这些与移位的位数无关,移位0位主要就是用了js的内部特性做了前两种转换。

三、Uint32类型是如何转换的

  1. 如果不能转换为Number,那就为0
  2. 如果为非整数,先转换为整数,参考公式sign(n) ⋅ floor(abs(n))
    1
    2
    3
    4
    function ToInteger(x) {
    x = Number(x);
    return x < 0 ? Math.ceil(x) : Math.floor(x);
    }
  3. 如果是正数,返回正数,如果是负数,返回负数 + 2的30次方
    1
    2
    3
    4
    5
    6
    function modulo(a, b) {
    return a - Math.floor(a/b)*b;
    }
    function ToUint32(x) {
    return modulo(ToInteger(x), Math.pow(2, 32));
    }

四、总结

x >>> 0本质上就是保证x有意义(为数字类型),且为正整数,在有效的数组范围内(0 ~ 0xFFFFFFFF),且在无意义的情况下缺省值为0。一个小小的表达式,隐藏着着多重的异常处理。

本文作者:bbcfive
版权声明:本文首发于bbcfive的博客,转载请注明出处!