为了账号安全,请及时绑定邮箱和手机立即绑定

為什麼999.222<<0 會得到整數999 ? javascript

為什麼999.222<<0 會得到整數999 ? javascript

哈士奇WWW 2018-09-11 13:38:10
利用這段代碼color = "#"+ (Math.random()*0xffffff<<0).toString(16);實現了隨機得到顏色但是實在不明白為什麼?這裡有解釋到一點 但也不明白http://www.cnblogs.com/rubylo...基本实现4的改进,利用左移运算符把0xffffff转化为整型。这样就不用记16777215了。由于左移运算符的优先级比不上乘号,因此随机后再左移,连Math.floor也不用了。如果x.abcd << 0 這樣也可以得到整數 x ,那又和Math.floor(x.abcd) 有什麼差別呢?
查看完整描述

1 回答

?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

这种问题,看规范就知道啦

移位运算在内部是啥样的?

12.8.3.1 Runtime Semantics: Evaluation

ShiftExpression : ShiftExpression << AdditiveExpression

  1. Let lref be the result of evaluating ShiftExpression.

  2. Let lval be GetValue(lref).

  3. ReturnIfAbrupt(lval).

  4. Let rref be the result of evaluating AdditiveExpression.

  5. Let rval be GetValue(rref).

  6. ReturnIfAbrupt(rval).

  7. Let lnum be ToInt32(lval).

  8. ReturnIfAbrupt(lnum).

  9. Let rnum be ToUint32(rval).

  10. ReturnIfAbrupt(rnum).

  11. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.

  12. Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer.

关键就是我标红的那一步,这一步会把变量lvalToInt32的运算,而这个lval就是来自我们移位运算的左值,就是你的999.222

接下来,再来看看ToInt32做了啥:

7.1.5 ToInt32 ( argument )

The abstract operation ToInt32 converts argument to one of 2^32 integer values in the range −2^31 through 2^31−1, inclusive. This abstract operation functions as follows:

  1. Let number be ToNumber(argument).

  2. ReturnIfAbrupt(number).

  3. If number is NaN, +0, −0, +∞, or −∞, return +0.

  4. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)).

  5. Let int32bit be int modulo 2^32.

  6. If int32bit ≥ 2^31, return int32bit − 2^32, otherwise return int32bit.

关键的那步我也给你标出来了,这里会把输入值直接取整。
所以,给一个浮点数做0的移位运算,结果就是取整。

对于Math.floor,规范没说具体实现,只给了一句话——

Returns the greatest (closest to +∞) Number value that is not greater than x and is equal to a mathematical integer. If x is already an integer, the result is x.
返回不大于x的最大整数;假如x已经是整数了,那么返回x

Math.floor的实现没给出,但是移位取整中间还多了好几个步骤,除了写代码的时候能稍微简洁一点以外,我觉得还是Math.floor更好点。

另外,ToInt32里面的那个floor运算是这么实现的:

floor(x) = x−(x modulo 1)

modulo是取模运算的意思,x1取模,那就是求x的小数部分,随后x剪掉了自己的小数部分,那就剩下整数了嘛。

必须要注意的是,ToInt32中是先取绝对值然后再取整的,所以在负数区间内,<< 0Math.floor的结果是不一样的。
Math.floor返回的是不大于输入值的最大整数,那么肯定就有Math.floor(-1.5) = -2
而对于<< 0运算,它是先取绝对值,然后取整,最后再把符号弄回去,那么就有-1.5 << 0 = -1


查看完整回答
反对 回复 2018-10-17
  • 1 回答
  • 0 关注
  • 587 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信