想知道有没有任何非平凡的方法来找到数字的符号 (signum函数)?
可能有比显而易见的方法更短、更快、更优雅的解决方案。
var sign = number > 0 ? 1 : number < 0 ? -1 : 0;
简短回答!
使用这个方法,您就能安全且快速地操作(来源:moz)。
if (!Math.sign) Math.sign = function(x) { return ((x > 0) - (x < 0)) || +x; };
您可能需要查看性能和类型转换比较的fiddle
很长一段时间已经过去了。下面的内容主要是出于历史原因。
结果
目前我们有以下解决方案:
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) -> NaN
, sign("0") -> NaN
由于在JS中Infinity
是一个合法的数字,因此这个解决方案似乎并不完全正确。
3. 这种方法... 但非常缓慢[最慢]
function sign(x) { return (x > 0) - (x < 0); }
4. 使用位移
快速,但sign(-Infinity) -> 0
function sign(x) { return (x >> 31) + (x > 0 ? 1 : 0); }
5. 安全类型的 [超级快速]
! 看起来浏览器(尤其是 Chrome 的 V8 引擎)会进行一些神奇的优化,这种解决方案比其他方案表现更好,甚至比 (1.1) 还要快,尽管它包含了两个额外的操作并且从逻辑上讲不可能更快。
function sign(x) {
return typeof x === 'number' ? x ? x < 0 ? -1 : 1 : x === x ? 0 : NaN : NaN;
}
工具
欢迎提出改进建议!
[离题] 接受的答案
Andrey Tarantsov - 艺术加分100,但不幸的是比明显的方法慢了大约5倍
Frédéric Hamidi - 目前为止最被赞同的答案,有点酷,但我认为这绝对不是正确的做法。另外,它不能正确处理无穷大的数字,你知道的,这也是数字。
kbec - 是对明显解决方案的改进。不算革命性,但综合考虑,我认为这种方法是最好的。请投他一票 :)
only integers
测试。此外,JSPerf只是在执行它的工作,这不是喜欢或不喜欢的问题。 :) - Alba Mendeztypeof x === "number"
对性能有一些神奇的影响。请多运行几次,特别是在FF、Opera和IE上进行测试以明确结果。 - disfatedMath.sign()
(0===0,不像“安全模式”那样快),该方法出现在 Firefox25 中并将在 Chrome 中推出。 - Alex K.