javascript 中的 Number.sign()

IT技术 javascript algorithm numbers sign
2021-03-05 14:41:32

想知道是否有任何重要的方法可以找到数字的符号(符号函数)?
可能比显而易见的解决方案更短/更快/更优雅

var sign = number > 0 ? 1 : number < 0 ? -1 : 0;

简短的回答!

使用它,您将安全快捷(来源:moz

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

您可能想查看性能和类型强制比较小提琴

很长时间过去了。进一步主要是历史原因。


结果

目前我们有这些解决方案:


1.明显快速

function sign(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }

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

function sign(x) { return x ? x < 0 ? -1 : 1 : 0; }

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


2.优雅,简短,没那么快【最慢】

function sign(x) { return x && x / Math.abs(x); }

小心: sign(+-Infinity) -> NaNsign("0") -> NaN

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


3.美术...但很慢[最慢]

function sign(x) { return (x > 0) - (x < 0); }

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

function sign(x) { return (x >> 31) + (x > 0 ? 1 : 0); }

5.类型安全[megafast]

似乎浏览器(尤其是 chrome 的 v8)进行了一些神奇的优化,结果证明这个解决方案比其他解决方案的性能要高得多,甚至比 (1.1) 还要好,尽管它包含 2 个额外的操作,而且逻辑上永远不会更快。

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

工具

欢迎改进!


[Offtopic] 接受的答案

  • Andrey Tarantsov - 艺术 +100,但遗憾的是它比明显的方法慢了大约 5 倍

  • Frédéric Hamidi - 不知何故,这是最受好评的答案(在写作时间),它有点酷,但这绝对不是应该如何做的,恕我直言。它也不能正确处理无穷大数字,你知道,它们也是数字。

  • kbec - 是对明显解决方案的改进。不是革命性的,但综合起来,我认为这种方法是最好的。投票给他:)

6个回答

更优雅的快速解决方案版本:

var sign = number?number<0?-1:1:0
-1 用于将三元混合在一起 var sign = (number)? ((number < 0)? -1 : 1 ) : 0
2021-05-07 14:41:32
Math.sign(number)
2021-05-15 14:41:32

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

var sign = number && number / Math.abs(number);
你可能想要var sign = number && number / Math.abs(number);以防万一number = 0
2021-04-27 14:41:32
你是目前最好的。但我希望将来会有更多的答案。
2021-05-10 14:41:32
@NullUserException,你说得对,0需要特殊情况。答案相应更新。谢谢 :)
2021-05-11 14:41:32

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

function sgn(x) {
  return (x > 0) - (x < 0);
}
等待。有错误: for (x = -2; x <= 2; x++) console.log((x > 1) - (x < 1)); 给出 [-1, -1, -1, 0, 1] for (x = -2; x <= 2; x++) console.log((x > 0) - (x < 0)); 给出正确的 [-1, -1, 0, 1, 1]
2021-05-21 14:41:32

这不应该支持 JavaScript (ECMAScript) 的带符号零吗?在“megafast”函数中返回 x 而不是 0 时似乎有效:

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

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

返回 x 的符号,指示 x 是正数、负数还是零。

  • 如果 x 为 NaN,则结果为 NaN。
  • 如果 x 为 -0,则结果为 -0。
  • 如果 x 为 +0,则结果为 +0。
  • 如果 x 为负且不是 -0,则结果为 -1。
  • 如果 x 为正数且不为 +0,则结果为 +1。
令人难以置信的快速和有趣的机制,我印象深刻。等待更多测试。
2021-05-13 14:41:32

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

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

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