7

JavaScript で数値の記号を削除したい。jsperf ( http://jsperf.com/remove-sign-from-number )で既に調べたテスト ケースを次に示します。

if(n < 0) n *= -1;

if(n < 0) n = -n;

n = Math.abs(n)

(n < 0) && (n *= -1)

(n < 0) && (n = -n)

n = Math.sqrt(n*n)

これらのテストによると:if(n < 0) n *= -1良い解決策のようです。

それを行うための、より良い、節約的で効率的な方法を知っていますか?

編集 1: Nikhil のMath.sqrtケースを追加しましたsqrtが、通常、ほとんどのシステムで非常に低速です。

編集 2:ビットごとの ops に対する Jan の提案は、場合によっては高速になる可能性がありますが、小数桁も削除されるため、私にはうまくいきません。

4

6 に答える 6

3

より良い回答が表示されなかったため、この回答の調査結果を自分で要約します。

  1. if(n < 0) n *= -1現在最良の選択です。ほとんどのプラットフォームで適切に機能し、非常に読みやすいです。また、小数も保持されます。
  2. などの他のバリアントは、n = Math.abs(n)他のプラットフォームでより高速になる場合があります。しかし、利益は通常数パーセントにすぎません。ブラウザ/プラットフォームを事前に検出し、いずれかのバリアントを使用するプラットフォーム依存のコードを構築することを検討してください。これにより、各プラットフォームで最高のパフォーマンスが得られますが、多くのオーバーヘッドが発生します。
  3. ビット単位の演算子を検討するときは注意してください。一部のプラットフォームでは高速になる可能性がありますが、プログラムのセマンティクスが変わる可能性があります (小数部の削除)。
于 2013-06-17T08:29:18.353 に答える
0

別の方法は次のとおりです。

n * (n>>31|!!n)(必ずしもすべてのブラウザーで最速であるとは限りません。別の方法です)

それは常に正の数を与えます。基本的に>>すべてのビットをシフトし、符号を保持します。That is then it is then bitwise OR'd with 0 or 1 (代わりに正の場合)、いずれかを生成します -1, 0 , または 1. つまり、符号はそれ自体で乗算され、常に偶数になります。

または、単純な三項演算でも:

n * (n < 0 ? -1 : 1)

また

n = n < 0 ? -n : n

n > 0 || (n *= -1)2番目のものは、OPの元の jsPerf:およびからの他のいくつかと同様に、ブラウザ全体で一貫して高速に見えますn < 0 && (n = -n)。これらも一貫して高速です。

jsPerf: https://jsperf.com/remove-sign-from-a-number

于 2017-10-01T04:21:58.373 に答える