今日はオンラインゲームの物理ライブラリをチェックアウトしていて、~~演算子に出会いました。単一の〜がビット単位のNOTであることは知っていますが、それは~~をNOTのNOTにし、同じ値を返しますね?
今日はオンラインゲームの物理ライブラリをチェックアウトしていて、~~演算子に出会いました。単一の〜がビット単位のNOTであることは知っていますが、それは~~をNOTのNOTにし、同じ値を返しますね?
回答:
ビットごとの演算子は暗黙的にオペランドを符号付き32ビット整数に変換するため、小数点以下のすべてを削除します。これは、オペランドが(浮動小数点)数値でも文字列でも機能し、結果は数値になります。
つまり、次の結果が得られます。
function(x) {
if(x < 0) return Math.ceil(x);
else return Math.floor(x);
}
xが-(2 31)と2 31-1の間にある場合のみ。それ以外の場合、オーバーフローが発生し、数値は「循環」します。
これは、関数の文字列引数を数値に変換するのに役立つと考えられますが、オーバーフローの可能性があることと、非整数での使用が正しくないことの両方のため、「コードゴルフ」以外の方法では使用しません(つまり、読みやすさと堅牢性を犠牲にして、プログラムのソースコードからバイトを無意味にトリミングします)。+xまたはNumber(x)代わりに使用します。
たとえば、-43.2という数値は次のとおりです。
-43.2 10 = 11111111111111111111111111010101 2
符号付き(2の補数)32ビットの2進数。(JavaScriptは小数点以下を無視します。)ビットを反転すると、次のようになります。
NOT -43 10 = 00000000000000000000000000101010 2 = 42 10
再び反転すると、次のようになります。
NOT 42 10 = 11111111111111111111111111010101 2 = -43 10
これは、Math.floor(-43.2)負の数がゼロから離れずにゼロに丸められるという点で異なります。(floor関数は-44に等しくなりますが、数値が正か負かに関係なく、常に次に低い整数に切り捨てられます。)
~~。
最初の〜演算子は、オペランドを整数に強制し(おそらく値を文字列またはブール値に強制した後)、次に最下位の31ビットを反転します。公式にはECMAScriptの数値はすべて浮動小数点ですが、一部の数値はSpiderMonkeyエンジンで31ビット整数として実装されています。
これを使用して、1要素の配列を整数に変換できます。浮動小数点はCの規則に従って変換されます。小数部分の切り捨て。
次に、2番目の〜演算子はビットを反転し、整数になることを知っています。空のオブジェクト{}はtrueと評価され、~~ {}はfalseと評価されるため、これは条件ステートメントで値をブール値に強制することとは異なります。
js>~~"yes"
0
js>~~3
3
js>~~"yes"
0
js>~~false
0
js>~~""
0
js>~~true
1
js>~~"3"
3
js>~~{}
0
js>~~{a:2}
0
js>~~[2]
2
js>~~[2,3]
0
js>~~{toString: function() {return 4}}
4
js>~~NaN
0
js>~~[4.5]
4
js>~~5.6
5
js>~~-5.6
-5
~~undefined // 0
~~null // 0
~は、最初の説明~と同じことを行い、その逆も同様です。~オペレータは単項演算子であり、右から左にinterperetedされる~~Xようなもので~(~X)ないような(~~)X(シンタックスエラーされるであろう)
ECMAScript 6では、同等のもの~~はMath.truncです。
小数桁を削除して、数値の整数部を返します。数値は丸められません。
Math.trunc(13.37) // 13
Math.trunc(42.84) // 42
Math.trunc(0.123) // 0
Math.trunc(-0.123) // -0
Math.trunc("-1.123")// -1
Math.trunc(NaN) // NaN
Math.trunc("foo") // NaN
Math.trunc() // NaN
ポリフィル:
function trunc(x) {
return x < 0 ? Math.ceil(x) : Math.floor(x);
}
する~ようです-(N+1)。したがって~2 == -(2 + 1) == -3、-3でもう一度実行すると、それは元に戻ります~-3 == -(-3 + 1) == 2。おそらく、文字列を単純な方法で数値に変換するだけです。
このスレッドを参照してください:http : //www.sitepoint.com/forums/showthread.php?t=663275
また、より詳細な情報はこちらから入手できます:http : //dreaminginjavascript.wordpress.com/2008/07/04/28/
与えられ~Nている-(N+1)、~~Nそしてあります-(-(N+1) + 1)。これは明らかに、きちんとしたトリックにつながります。
ほんの少しの警告。ここでの他の答えは私にいくつかの問題を引き起こしました。
その目的は、浮動小数点数の小数点以下を削除することですが、バグの危険を引き起こすいくつかのコーナーケースがあります。~~は避けることをお勧めします。
まず、~~は非常に大きな数では機能しません。
~~1000000000000 == -727279968
別の方法として、Math.trunc()(Gajusが述べたようMath.trunc()に、浮動小数点数の整数部分を返しますが、ECMAScript 6準拠のJavaScriptでのみ使用できます)を使用します。これを行うことで、Math.trunc()ECMAScript-6以外の環境用に独自の環境をいつでも作成できます。
if(!Math.trunc){
Math.trunc = function(value){
return Math.sign(value) * Math.floor(Math.abs(value));
}
}
私は参考のためにこれについてブログ投稿を書きました:http : //bitlords.blogspot.com/2016/08/the-double-tilde-x-technique-in.html
この演算子を効率的に使用する方法の例を次に示します。
leftOffset = -(~~$('html').css('padding-left').replace('px', '') + ~~$('body').css('margin-left').replace('px', '')),
ソース: