在JavaScript中快速保存删除签名数字的方法

在JavaScript中快速保存删除签名数字的方法,javascript,performance,numbers,signed,jsperf,Javascript,Performance,Numbers,Signed,Jsperf,我想删除JavaScript中的数字符号。以下是我已经在jsperf()上检查过的测试用例 if(n 0; // 4294967295 我猜你的意思是数学.sqrt(n*n)?我在我的案例中添加了一个,但是它比其他的要慢得多。这是一种对cpu来说很慢的方法。它需要计算功率,然后我可以问一下为什么在javascript中需要这个吗?Javascript不应该是最快的语言。为什么不使用C或汇编呢?我正在用CoffeeScript实现一个小型的概念验证游戏引擎,需要为一些内部数学去掉这个符号。您的答案

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

if(n<0)n*=-1;
如果(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关于位运算的建议在某些情况下可能更快,但也会删除小数,因此对我不起作用。

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

位运算符最快,请参阅

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

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

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

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

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

    甚至是简单的三元运算:

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

    n=n<0-n:n

    第二个在不同浏览器中似乎都是快速的,OP最初的jsPerf中的一些浏览器也是如此:
    n>0 | |(n*=-1)
    n<0&(n=-n)
    ,它们也都是快速的

    jsPerf:

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

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

    1>>>0;//1.
    -1 >>> 0; // 4294967295
    
    我猜你的意思是
    数学.sqrt(n*n)
    ?我在我的案例中添加了一个,但是它比其他的要慢得多。这是一种对cpu来说很慢的方法。它需要计算功率,然后我可以问一下为什么在javascript中需要这个吗?Javascript不应该是最快的语言。为什么不使用C或汇编呢?我正在用CoffeeScript实现一个小型的概念验证游戏引擎,需要为一些内部数学去掉这个符号。您的答案看起来很有希望(尽管我仍然坚持使用if-then*=-1),这似乎是一个更好的选择,可以在浏览器间获得良好的平均性能,尤其是可读性。如果您详细解释代码的功能,以及is如何提供正确的结果(删除符号并保留值),我可能会接受它作为答案。细节总是好的,特别是对所有其他读者。不是每个人都很了解位操作,尤其是在Javascript社区。对不起,我刚刚测试了一些值,您的解决方案还将JS浮点转换为“int”(是的,我知道JS只使用浮点)。那不是我想要的。我还需要删除非固定号码的标志:(不同浏览器的性能特征差异很大。在SeaMonkey上,
    Math.abs
    明显优于其他浏览器。在Konqueror上,按位(
    if(n<0)n=~n+1
    )非常出色[code>&变体都不好]和
    Math.abs
    糟糕。总之,
    if(n<0)n*=-1
    if(n<0)n=-n
    似乎是安全的,在任何地方都不会发出太大的臭味。按位运算符的一个问题是,它们将数字强制为32位整数-如果
    n
    超出该范围,则按位方式将产生垃圾。它不仅去掉符号位,还为每个负数创建不同的数字这不是OP想要的——他们想要的只是符号消失。(而且,
    1>>0
    是1而不是100!)啊。谢谢Alexander,编辑。
    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 = ~n+1;