数の符号(signum関数)を見つけるための重要な方法があるのだろうか?
明白なものよりも短い/速い/よりエレガントなソリューションかもしれません
var sign = number > 0 ? 1 : number < 0 ? -1 : 0;
短い答え!
これを使用すると、安全で高速になります(ソース:moz)
if (!Math.sign) Math.sign = function(x) { return ((x > 0) - (x < 0)) || +x; };
パフォーマンスと型強制の比較フィドルを見たいと思うかもしれません
長い時間が経ちました。さらに、主に歴史的な理由によるものです。
結果
今のところ、これらのソリューションがあります:
1.明白で速い
function sign(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }
1.1。kbecからの変更-1つのタイプのキャストが少なく、パフォーマンスが高く、短い[最速]
function sign(x) { return x ? x < 0 ? -1 : 1 : 0; }
注意: sign("0") -> 1
2.エレガント、短く、それほど速くない[遅い]
function sign(x) { return x && x / Math.abs(x); }
注意: sign(+-Infinity) -> NaN
、sign("0") -> NaN
Infinity
JSの合法的な数の時点で、このソリューションは完全に正しいとは思われません。
3.アート...しかし非常に遅い[最も遅い]
function sign(x) { return (x > 0) - (x < 0); }
4.ビットシフトを高速に使用します
が、sign(-Infinity) -> 0
function sign(x) { return (x >> 31) + (x > 0 ? 1 : 0); }
5.タイプセーフ[megafast]
!ブラウザー(特にchromeのv8)は魔法の最適化を行っているようで、このソリューションは(1.1)よりも、2つの追加の操作を含み、論理的には決して高速化できないにもかかわらず、他のものよりもはるかに高いパフォーマンスを発揮します。
function sign(x) {
return typeof x === 'number' ? x ? x < 0 ? -1 : 1 : x === x ? 0 : NaN : NaN;
}
ツール
- jsperfパフォーマンステスト;
- フィドル -型キャストテスト;
改善は大歓迎です!
[オフトピック]受け入れられた回答
Andrey Tarantsov-アートの+100ですが、残念なことに、明らかなアプローチよりも約5倍遅いです
フレデリック・ハミディ -どういうわけか(執筆期間中)最も支持された答えであり、それはちょっとクールですが、物事をどのように行うべきかは間違いなく、私見です。また、それは数値でもある無限数を正しく処理しません。
kbec-明白なソリューションの改良版です。それほど革命的ではありませんが、すべてをまとめると、このアプローチが最良だと思います。彼に投票する:)
test everything
バージョンを実行すると、Safeは特別な値のテストを拒否するため、より高速になります!only integers
代わりにテストを実行してみてください。また、JSperfは彼の仕事をしているだけで、好きなことではありません。:)
typeof x === "number"
にいくつかの魔法をかけることが判明しました。より明確にするために、特にFF、Opera、IEを実行してください。
0
特別なケースであるということです