1 回答
TA贡献1829条经验 获得超6个赞
这种问题,看规范就知道啦
移位运算在内部是啥样的?
12.8.3.1 Runtime Semantics: Evaluation
ShiftExpression :
ShiftExpression
<<AdditiveExpression
Let 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
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
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
x
and is equal to a mathematical integer. Ifx
is already an integer, the result isx
.
返回不大于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
。
添加回答
举报