JavaScript位运算符

JavaScript的位运算符为什么可以取整呢?取整的原理是什么呢?
比如 12.334 << 0 得出的结果是12,请问为什么呢?

阅读 4.8k
6 个回答

位运算符用于对二进制位进行计算,这些位运算符直接处理每一个比特位(bit),所以是非常底层的运算,好处是速度极快,缺点是很不直观,许多场合不能使用它们

位运算符只对整数起作用,如果一个运算子不是整数,会自动转为整数后再执行。虽然在JavaScript内部,数值都是以64位浮点数的形式储存,但是做位运算的时候,是以32位带符号的整数进行运算的,并且返回值也是一个32位带符号的整数

回到上面的问题:
这是左移运算符,左移运算符表示将一个数的二进制值向左移动指定的位数,尾部补0,即乘以2的指定次方(最高位即符号位不参与移动)。

左移0位,就相当于将该数值转为32位整数,等同于取整,对于正数和负数都有效。

日经问题

因为JavaScript引擎会先把浮点数转换成整数再移位,而你移位的位数是0,结果当然就是当前浮点数的整数喽。

位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。ECMAScript 中的所有数
值都以 IEEE-754 64 位格式存储,但位操作符并不直接操作 64 位的值。而是先将 64 位的值转换成 32 位
的整数,然后执行操作,最后再将结果转换回 64 位。对于开发人员来说,由于 64 位存储格式是透明的,
因此整个过程就像是只存在 32 位的整数一样

位运算 的操作数都会先对其进行抽象的 ToInt32 操作

链接描述

ToUint32: (Unsigned 32 Bit Integer)

1.Let number be the result of calling ToNumber on the input argument.
2.If number is NaN, +0, −0, +∞, or −∞, return +0.
3.Let posInt be sign(number) × floor(abs(number)).
4.Let int32bit be posInt modulo 232; that is, a finite integer value k of Number type with positive sign and less than 232 in magnitude such that the mathematical difference of posInt and k is mathematically an integer multiple of 232.
5.Return int32bit.

三四步就是个求整取余数的过程

<<0 对实际的值没有进行具体的位移操作,但是仍然会进行其中的 ToInt32 操作,在一定的范围内就是简单的按绝对值取整,超出这个范围就会变成意想不到的值

因为javascript的位运算符只对32位整数有效,所以在进行位运算的时候会把运算符两边的数进行强制转换成32位的整数,所以对小数进行位运算会变成整数。12.334 << 0表达式两边取整之后就相当于12<<0,因此位运算符可以取整,不过只限32位,超过32位就会出错。

看代码:

12.334.toString(2);//"1100.010101011000000100000110001001001101110100101111" //转为二进制
所以 12.334 << 0 相当于 二进制 1100 向左移送0位 ;  
parseInt('1100',2) //12

这个涉及到JavaScript对位运算符的处理。我们要知道,js中数值都是IEEE 764标准,但标准中规定<<>>~等位运算符会对仅为32位的数值定义,所有会有一个ToInt32的抽象操作,即32位有符号整数。<< 0表明位移为零,所有就截断了小数部分。下面的也可以:

~~12.334

参考:you dont konw js
you dont know js

对于使用位运算是否有副作用,在知乎这里有讨论

我的看法是,使用位运算符有点geek,但语义化并不清楚。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题