sinではなくsign関数です。受け取った数値が正の数か負の数か0かを返します。
まず原始的実装
sign関数は簡単に実装すると以下のようになります。
function sign(n){ return n===0?0:n>0?1:-1; }
もう少し短くするとこんなかんじです
function sign(n){ return n>0?1:n<0?-1:0; }
多分限界まで短いのはこんなかんじです
function sign(n){ return n>0?1:n?-1:0; }
ビットを用いて実装
しかしこれでは味気ないので折角です、ビット整数の知識を用いて書いてみましょう。
まず整数を32ビット符号付き整数に変換します。すると、初めのビットが符号を表すようになります。初めのビットが0なら正の数、1なら負の数となります。
ただ、これでは0も正の数と判定されてしまいます。悔しいですが、私ではこれはビットを用いて判定できないので別処理にします。うまくできそうなんですがね…
function sign(n){ return !n?0:(n|0)>>>31?-1:1; }
もうすこしだけ改善。
function sign(n){ return -(n>>>31)||(n?1:0); }
短くなりましたが、-を判定する部分以外は普通にやってしまっているので残念ですね。なんとかできそうなのですが…
おまけ: 速度測ってみた
ビットを使わない原始的実装をsign1、ビットを使う実装をsign2とします。計測は以下のコードで行いました(sign関数はそれぞれsign1、sign2に変更して測定しました)。
console.time('sign'); for(var i=0;i<1000000;i=0|i+1){ sign(1); sign(10); sign(12345); sign(-1); sign(-10); sign(-1); sign(0); } console.timeEnd('sign');
結果はどちらも平均5msくらいでほぼ違いがありませんでした。ちょっとsign1が早かったかな、というくらいです。