JS使用~、>>、<<、>>>、|来取整,有啥区别
在 JavaScript 中,可以使用位运算符 ~
、>>
、<<
、>>>
和 |
来实现取整操作,但它们的原理和效果有所不同。以下是它们的区别:
1. |
(按位或)取整
-
原理:
x | 0
将x
与0
进行按位或操作,会将x
转换为 32 位有符号整数(丢弃小数部分)。 -
效果:
-
正数:向下取整(
Math.floor
)。 -
负数:向 0 取整(类似
Math.trunc
)。
-
-
示例:
3.14 | 0; // 3 -3.14 | 0; // -3
2. ~~
(双按位非)取整
-
原理:
~~x
等价于-(-x | 0) | 0
,即两次取反,仍然会转换为 32 位整数。 -
效果:
-
正数:向下取整(
Math.floor
)。 -
负数:向 0 取整(类似
Math.trunc
)。
-
-
示例:
~~3.14; // 3 ~~-3.14; // -3
3. >>
(有符号右移)取整
-
原理:
x >> 0
将x
右移 0 位,仍然会转换为 32 位有符号整数。 -
效果:
-
正数:向下取整(
Math.floor
)。 -
负数:向 0 取整(类似
Math.trunc
)。
-
-
示例:
3.14 >> 0; // 3 -3.14 >> 0; // -3
4. <<
(左移)取整
-
原理:
x << 0
将x
左移 0 位,仍然会转换为 32 位有符号整数。 -
效果:
-
正数:向下取整(
Math.floor
)。 -
负数:向 0 取整(类似
Math.trunc
)。
-
-
示例:
3.14 << 0; // 3 -3.14 << 0; // -3
5. >>>
(无符号右移)取整
-
原理:
x >>> 0
将x
转换为 32 位 无符号整数,适用于非负数。 -
效果:
-
正数:向下取整(
Math.floor
)。 -
负数:会转换为很大的正数(因为是无符号整数)。
-
-
示例:
3.14 >>> 0; // 3 -3.14 >>> 0; // 4294967293(即 2^32 - 3)
总结对比
运算符 | 取整方式 | 适用数值范围 | 是否支持负数 | 类似方法 | |
---|---|---|---|---|---|
`x | 0` | 向 0 取整 | 32 位有符号整数 | 是 | Math.trunc |
~~x | 向 0 取整 | 32 位有符号整数 | 是 | Math.trunc | |
x >> 0 | 向 0 取整 | 32 位有符号整数 | 是 | Math.trunc | |
x << 0 | 向 0 取整 | 32 位有符号整数 | 是 | Math.trunc | |
x >>> 0 | 向下取整 | 32 位无符号整数 | 否(负数会变正) | Math.floor (仅正数) |
注意事项
-
32 位限制:所有位运算取整都会将数值限制在 32 位范围内(
-2^31
到2^31-1
),超出会溢出。 -
负数处理:
-
|
、~~
、>>
、<<
对负数的取整方式是向 0 取整(类似Math.trunc
)。 -
>>>
对负数会返回无符号整数,通常不符合预期。
-
-
可读性:位运算取整虽然高效,但可读性较差,建议在必要时使用,或直接用
Math.trunc
、Math.floor
等标准方法。