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: Jan 的按位运算建议在某些情况下可能会更快,但也会删除小数位数,因此对我不起作用。

4

6 回答 6

3

由于没有出现更好的答案,我将自己总结这个答案中的发现。

  1. if(n < 0) n *= -1是目前最好的选择。它在大多数平台上都表现得相当好,并且非常易读。它还保留小数部分。
  2. 其他变体,例如n = Math.abs(n),在其他平台上可能更快。但收益通常只有几个百分比。您可以考虑预先检测浏览器/平台并构建使用一种或另一种变体的依赖于平台的代码。这可以在每个平台上为您提供最佳性能,但会带来很多开销。
  3. 在考虑按位运算符时要小心,它们在某些平台上可能更快,但会改变程序的语义(删除小数部分)。
于 2013-06-17T08:29:18.353 回答
2

位运算符是最快的,看结果

if(n < 0) n = ~n+1;
于 2013-06-12T11:25:32.483 回答
1

你可以使用 Math.abs()。它返回数字的绝对值

于 2020-06-22T12:50:38.750 回答
0

这是另一种方式:

n * (n>>31|!!n)(不一定是所有浏览器上最快的,只是另一种方式)

那总是会给出一个正数。基本上>>移动所有位并保持符号。然后将其与 0 或 1(如果为正)进行按位或运算,生成 -1、0 或 1。这意味着符号自身相乘,使其始终为偶数。

甚至可以使用简单的三元运算:

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

或者

n = n < 0 ? -n : n

第二个在浏览器中似乎一直很快,就像 OP 的原始 jsPerf: n > 0 || (n *= -1)and中的其他一些一样n < 0 && (n = -n),它们也一直很快。

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

于 2017-10-01T04:21:58.373 回答
0

不确定这是否是 XY 问题类型的情况,但零填充右移 0 会消除符号位。我想不出更快的方法。

1 >>> 0; // 1
-1 >>> 0; // 4294967295
于 2021-03-29T11:00:53.423 回答
-1

您也可以使用 n=Math.sqrt(n^n)

于 2013-06-12T10:03:18.013 回答