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
xand is equal to a mathematical integer. Ifxis 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。
添加回答
舉報
