1

次の例を見ると、 , forMath.floor(x)と同等のように見えます。それは本当に本当ですか?はいの場合、なぜですか? (またはどのように計算されますか?)x | 0x >= 0x | 0

x = -2.9; console.log(Math.floor(x) + ", " + (x | 0));   // -3, -2
x = -2.3; console.log(Math.floor(x) + ", " + (x | 0));   // -3, -2
x = -2;   console.log(Math.floor(x) + ", " + (x | 0));   // -2, -2
x = -0.5; console.log(Math.floor(x) + ", " + (x | 0));   // -1, 0
x = 0;    console.log(Math.floor(x) + ", " + (x | 0));   //  0, 0
x = 0.5;  console.log(Math.floor(x) + ", " + (x | 0));   //  0, 0
x = 2;    console.log(Math.floor(x) + ", " + (x | 0));   //  2, 2
x = 2.3;  console.log(Math.floor(x) + ", " + (x | 0));   //  2, 2
x = 2.9;  console.log(Math.floor(x) + ", " + (x | 0));   //  2, 2
x = 3.1;  console.log(Math.floor(x) + ", " + (x | 0));   //  3, 3

これは、Javascript で整数除算を実行するのに役立ち(5 / 3) | 0ますMath.floor(5 / 3)

4

5 に答える 5

4

ビット単位の演算子は、数値を 32 ビット シーケンスに変換します。したがって、あなたが提案している代替手段は、正の符号付き 32 ビット浮動小数点数、つまり から ( ) までの数値でのみ機能0+2,147,483,647ます2^31-1

Math.floor(2147483646.4); // 2147483647
2147483646.4 | 0; // 2147483647
// but…
Math.floor(2147483648.4); // 2147483648
2147483648.4 | 0; // -2147483648

もう 1 つの違い:xが数値でない場合、 の結果は の結果x | 0と異なる場合がありMath.floor(x)ます。

Math.floor(NaN); // NaN
NaN | 0; // 0

それ以外はMath.floor()、正の数が使用されている限り、結果は の結果と同様になるはずです。

いくつかの例とパフォーマンス テストを次に示します: http://jsperf.com/rounding-numbers-down

于 2012-02-22T09:22:41.027 に答える
4

ECMAScript 仕様に従って、§11.10 Binary Bitwise Operators:

Semantics
The production A : A @ B, where @ is one of the bitwise operators in the productions 
above, is evaluated as follows:
1. Let lref be the result of evaluating A.
2. Let lval be GetValue(lref).
3. Let rref be the result of evaluating B.
4. Let rval be GetValue(rref).
5. Let lnum be ToInt32(lval).
6. Let rnum be ToInt32(rval).
7. Return the result of applying the bitwise operator @ to lnum and rnum. The result 
   is a signed 32 bit integer.

は次のようx | yに計算されます: xandyが解析され、演算子がInt32適用されます。|

于 2012-02-22T09:25:42.380 に答える
3

JS のビット操作は 32 ビットです。つまり、float は最初に「int」に「キャスト」されます。

"2.6" | 0 = 2parseIntが呼び出されていることを示します。

于 2012-02-22T09:22:10.787 に答える
2

垂直バーは、ビットごとの OR 演算子です。0 のビットはすべて 0 でx|0あるため、理論上はノーオペレーションです。ただし、それを評価するには、オペランドは整数でxなければならないため、最初に浮動小数点から整数に変換する必要があります。変換は小数部分を削除することによって行われるため、そうです、一部の x >= 0 ではx|0==になりMath.floor(x)ます。

結果は、内部整数型のサイズと符号に依存することに注意してください。たとえば、次のようになります。

2147483648|0     == -2147483648     // 0x80000000
Math.pow(2,32)|0 == 0               // the lowest 32 bits are all 0
于 2012-02-22T09:20:15.163 に答える
1

(x | 0) は "." の後のビットを削除するため、次の真の関係を取得できます。

x | 0 = (x < 0 ? -1 : 1) * Math.floor(Math.abs(x)) ;

x >> 0 は x | と同じ効果があります。0 なので :

x >> 0 = x | 0 = (x < 0 ? -1 : 1) * Math.floor(Math.abs(x)) ;
于 2012-02-22T09:11:46.607 に答える