猿问

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

利用這段代碼
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) 有什麼差別呢?


哈士奇WWW
浏览 588回答 1
1回答

肥皂起泡泡

这种问题,看规范就知道啦移位运算在内部是啥样的?12.8.3.1 Runtime Semantics: EvaluationShiftExpression :&nbsp;ShiftExpression&nbsp;<<&nbsp;AdditiveExpressionLet lref be the result of evaluating ShiftExpression.Let lval be GetValue(lref).ReturnIfAbrupt(lval).Let rref be the result of evaluating AdditiveExpression.Let rval be GetValue(rref).ReturnIfAbrupt(rval).Let lnum be&nbsp;ToInt32(lval).ReturnIfAbrupt(lnum).Let rnum be ToUint32(rval).ReturnIfAbrupt(rnum).Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer.关键就是我标红的那一步,这一步会把变量lval做ToInt32的运算,而这个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:Let number be ToNumber(argument).ReturnIfAbrupt(number).If number is NaN, +0, −0, +∞, or −∞, return +0.Let int be the mathematical value that is the same sign as number and whose magnitude is&nbsp;floor(abs(number)).Let int32bit be int modulo 2^32.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&nbsp;x&nbsp;and is equal to a mathematical integer. If&nbsp;x&nbsp;is already an integer, the result is&nbsp;x.返回不大于x的最大整数;假如x已经是整数了,那么返回x。Math.floor的实现没给出,但是移位取整中间还多了好几个步骤,除了写代码的时候能稍微简洁一点以外,我觉得还是Math.floor更好点。另外,ToInt32里面的那个floor运算是这么实现的:floor(x) = x−(x modulo 1)modulo是取模运算的意思,x对1取模,那就是求x的小数部分,随后x剪掉了自己的小数部分,那就剩下整数了嘛。必须要注意的是,ToInt32中是先取绝对值然后再取整的,所以在负数区间内,<< 0和Math.floor的结果是不一样的。Math.floor返回的是不大于输入值的最大整数,那么肯定就有Math.floor(-1.5) = -2。而对于<< 0运算,它是先取绝对值,然后取整,最后再把符号弄回去,那么就有-1.5 << 0 = -1。
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答