我想删除 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关于按位运算的建议在某些情况下可能会更快,但也会删除小数位,因此对我来说不起作用。
您可以使用
Math.abs()
。
它返回数字的绝对值
由于没有更好的答案出现,我将自己总结此答案中的发现。
if(n < 0) n *= -1
是目前最佳选择。它在大多数平台上都表现得相当好并且非常可读。它还保留小数部分。n = Math.abs(n)
,在其他平台上可能会更快。但收益通常只有几个百分点。您可以考虑预先检测浏览器/平台并构建使用一种或另一种变体的依赖于平台的代码。这可以为您在每个平台上提供最佳性能,但会带来大量开销。按位运算符是最快的,请参阅结果。
if(n < 0) n = ~n+1;
还有另一种方法:
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)
,它们也始终保持快速。
不确定这是否是 XY 问题类型的情况,但零填充右移 0 消除了符号位。我想不出更快的方法。
1 >>> 0; // 1
-1 >>> 0; // 4294967295
您也可以使用 n=Math.sqrt(n^n)