JavaScript中的Number.sign()

dis*_*ted 100 javascript algorithm numbers sign

想知道是否有任何寻找数字符号(signum函数)的重要方法?
可能是比较明显的解决方案更短/更快/更优雅的解决方案

var sign = number > 0 ? 1 : number < 0 ? -1 : 0;
Run Code Online (Sandbox Code Playgroud)

摘录简短

使用它,你会安全,快速

if (!Math.sign) Math.sign = function(x) { return ((x > 0) - (x < 0)) || +x; };
Run Code Online (Sandbox Code Playgroud)

结果

现在我们有这些解决方案:


1.明显而快速

function sign(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }
Run Code Online (Sandbox Code Playgroud)

1.1.来自kbec的修改- 一种类型转换更少,更高性能,更短[最快]

function sign(x) { return x ? x < 0 ? -1 : 1 : 0; }
Run Code Online (Sandbox Code Playgroud)

警告: sign("0") -> 1


2.优雅,短暂,不那么快[最慢]

function sign(x) { return x && x / Math.abs(x); }
Run Code Online (Sandbox Code Playgroud)

注意: sign(+-Infinity) -> NaN,sign("0") -> NaN

作为InfinityJS中的合法数字,这个解决方案似乎并不完全正确.


3.艺术......但速度很慢[慢]

function sign(x) { return (x > 0) - (x < 0); }
Run Code Online (Sandbox Code Playgroud)

4. 快速使用位移
,但是sign(-Infinity) -> 0

function sign(x) { return (x >> 31) + (x > 0 ? 1 : 0); }
Run Code Online (Sandbox Code Playgroud)

5.类型安全[megafast]

!似乎浏览器(特别是chrome的v8)进行了一些神奇的优化,这个解决方案比其他解决方案更高效,甚至比(1.1)更好,尽管它包含2个额外的操作,逻辑上永远不会更快.

function sign(x) {
    return typeof x === 'number' ? x ? x < 0 ? -1 : 1 : x === x ? 0 : NaN : NaN;
}
Run Code Online (Sandbox Code Playgroud)

工具

欢迎改进!


[Offtopic]接受的答案

  • 安德烈·塔兰索夫(Andrey Tarantsov) - 艺术品为+100,但遗憾的是它比明显的方法慢了约5倍

  • 弗雷德里克·哈米迪(FrédéricHamidi) - 不知何故是最受欢迎的答案(写作时间)并且它有点酷,但绝对不是应该如何做的事情,imho.你知道,它也无法正确处理无穷大数字,这也是数字.

  • kbec - 是明显解决方案的改进.这不是革命性的,但考虑到所有这些,我认为这种方法是最好的.为他投票:)

kbe*_*bec 79

更优雅的快速解决方案:

var sign = number?number<0?-1:1:0
Run Code Online (Sandbox Code Playgroud)

  • -1将你的三元糖化在一起`var sign =(number)?((数字<0)? - 1:1):0` (4认同)
  • Math.sign(数字) (2认同)

Fré*_*idi 28

将数字除以其绝对值也给出了它的符号.使用短路逻辑AND运算符允许我们使用特殊情况,0因此我们不会最终除以它:

var sign = number && number / Math.abs(number);
Run Code Online (Sandbox Code Playgroud)

  • 您可能想要`var sign = number && number/Math.abs(number);`以防`number = 0` (6认同)

And*_*sov 24

您正在寻找的函数称为signum,实现它的最佳方法是:

function sgn(x) {
  return (x > 0) - (x < 0);
}
Run Code Online (Sandbox Code Playgroud)

  • 等待.有错误:for(x = -2; x <= 2; x ++)console.log((x> 1) - (x <1)); 为(x = -2; x <= 2; x ++)console.log((x> 0) - (x <0))给出[-1,-1,-1,0,1]; 给出正确的[-1,-1,0,1,1] (3认同)

小智 13

这不应该支持JavaScript(ECMAScript)签名的零吗?在"megafast"函数中返回x而不是0时似乎有效:

function sign(x) {
    return typeof x === 'number' ? x ? x < 0 ? -1 : 1 : x === x ? x : NaN : NaN;
}
Run Code Online (Sandbox Code Playgroud)

这使它与ECMAScript的Math.sign(MDN)草案兼容:

返回x的符号,表示x是正数,负数还是零.

  • 如果x是NaN,则结果为NaN.
  • 如果x是-0,则结果为-0.
  • 如果x为+0,则结果为+0.
  • 如果x为负数而不是-0,则结果为-1.
  • 如果x为正且不为+0,则结果为+1.


Sal*_*ali 10

对于那些对最新浏览器感兴趣的人,在ES6版本中有一个原生的Math.sign方法.您可以在此处查看支持.

基本上它返回-1,1,0或者NaN

Math.sign(3);     //  1
Math.sign(-3);    // -1
Math.sign('-3');  // -1
Math.sign(0);     //  0
Math.sign(-0);    // -0
Math.sign(NaN);   // NaN
Math.sign('foo'); // NaN
Math.sign();      // NaN
Run Code Online (Sandbox Code Playgroud)