检测数字是否从负数变为正数或从正数变为负数

4
如何检测正变化或负变化?
例子:
1 变成 2 = 假
0 变成 1 = 假
因为它们都是正数
1 变成 -1 = 真
0 变成 -1 = 真
因为正数变成负数
-1 变成 0 = 真
-1 变成 1 = 真
因为负数变成正数
我喜欢...
var a_test,b_test;
if(a<0) {
    a_test = 'negative';
} else {
    a_test = 'positive';
}
if(b<0) {
    b_test = 'negative';
} else {
    b_test = 'positive';
}

if(a_test!==b_test) {
    alert('Yeah!');
}

测试用例: http://jsfiddle.net/e9QPP/

是否有更好的代码实现类似功能?


维基百科:负数是指小于零的实数。


如果其中一个为0而另一个不是,你确切地想要什么? - Denys Séguret
@dystroy 由于0既不是正数也不是负数,也许这个问题最好改为“比较两个数字的符号是否相同”或“检查一个数字是否为负数,另一个数字是否为非负数”。 - crush
5个回答

5
根据Python之禅,可读性至关重要。因此,我呈现更易读且通过代码审查的版本。
if (a < 0 && b >= 0 || a >= 0 && b < 0) {
    alert("Yeah");
}

是的!简单但对我来说最好 :D - l2aelba
1
是的,考虑到0这种特殊情况,这可能是最清晰的方法。我给你点赞。 - Denys Séguret
1
出乎我的意料,这个方法在所有版本的IE和Safari 5.1中都比我的位移技术更快。位移在Chrome、Firefox和Opera中胜出,但这个方法排名第二。因此,这个解决方案不仅易读,而且非常快速。 - crush
哦,最快的是@crush! - l2aelba
1
只在某些浏览器中有效。总的来说,我认为thefourtheye有最好的解决方案。 - crush

4

您似乎希望

if (a*b<0) alert('Yeah!');

如果您想把0看作正数,可以使用:
if (a*b<0 || (!(a*b) && a+b<0)) alert('Yeah!');

1
我不喜欢。因为溢出了 :p - Alma Do
零是正数还是负数? - l2aelba
1
仍需要更多的检查 a = 0, b = -1; - epascarello
我正在查看以下列出的情况:0 改为 -1 = true - epascarello
1
运算符将 0 视为正数。 - crush
显示剩余2条评论

3

选择一个合适的符号函数

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

那么,你的问题可以用清晰且(希望)简单的方式表达出来:
if (sign(a) !== sign(b)) {
  // Your code here
}

提供一个指向 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/sign 的链接会很不错。 - Tibos
@Tibos,这个答案没有使用 Math.sign() - epascarello
@epascarello 或许应该这样做。如果我们都自己编写略有不同的函数来完成相同的任务,最终会导致大量互操作性问题。当存在标准函数时,应该使用它并提供兼容的替代方案。 - Tibos

1

也许有点晚了,但我有同样的问题。

假设您现在知道a和b是数字,为什么不这样做:

if(a < 0 ? b >=0 : b < 0){
   // your code here
}

1

根据你的标准,似乎你只想比较两个数的符号。符号存储在数字的最高位中,因此,为了比较符号,我们可以简单地将数字的所有其他位移位,然后比较符号。

JavaScript中的数字是64位(double),因此我们需要将符号之前的63位移位:

if (a >>> 63 !== b >>> 63) alert('Yeah!');

这里有一个jsFiddle演示

这里有一个基于这4种方法的jsPerf比较

请注意,这假定数字为64位。我不知道规范是否将其限制为64位,但有可能存在(或将来会出现)数字由128位或更大数字表示的浏览器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接