在 JavaScript 中快速安全地删除有符号数字的符号

问题描述 投票:0回答:6

我想删除 JavaScript 中数字的符号。 这是我已经在 jsperf 检查过的测试用例

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

javascript performance numbers signed jsperf
6个回答
7
投票

您可以使用

Math.abs()
。 它返回数字的绝对值


5
投票

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

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

2
投票

按位运算符是最快的,请参阅结果

if(n < 0) n = ~n+1;

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)
n < 0 && (n = -n)
,它们也始终保持快速。

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


0
投票

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

1 >>> 0; // 1
-1 >>> 0; // 4294967295

-2
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.