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
。
添加回答
舉報