测试值是奇数还是偶数


183

我决定使用非常简单的算法创建简单的isEvenisOdd函数:

function isEven(n) {
  n = Number(n);
  return n === 0 || !!(n && !(n%2));
}

function isOdd(n) {
  return isEven(Number(n) + 1);
}

如果n具有某些参数,那是可以的,但是在许多情况下会失败。因此,我着手创建健壮的函数,以便在尽可能多的情况下提供正确的结果,以便仅测试javascript数字限制内的整数,其他所有结果均返回false(包括+和-无限)。注意零是偶数。

// Returns true if:
//
//    n is an integer that is evenly divisible by 2
//
// Zero (+/-0) is even
// Returns false if n is not an integer, not even or NaN
// Guard against empty string

(function (global) {

  function basicTests(n) {

    // Deal with empty string
    if (n === '') 
      return false;

    // Convert n to Number (may set to NaN)
    n = Number(n);

    // Deal with NaN
    if (isNaN(n)) 
      return false;

    // Deal with infinity - 
    if (n === Number.NEGATIVE_INFINITY || n === Number.POSITIVE_INFINITY)
      return false;

    // Return n as a number
    return n;
  }

  function isEven(n) {

    // Do basic tests
    if (basicTests(n) === false)
      return false;

    // Convert to Number and proceed
    n = Number(n);

    // Return true/false
    return n === 0 || !!(n && !(n%2));
  }
  global.isEven = isEven;

  // Returns true if n is an integer and (n+1) is even
  // Returns false if n is not an integer or (n+1) is not even
  // Empty string evaluates to zero so returns false (zero is even)
  function isOdd(n) {

    // Do basic tests
    if (basicTests(n) === false)
      return false;

    // Return true/false
    return n === 0 || !!(n && (n%2));
  }
  global.isOdd = isOdd;

}(this));

谁能看到上述任何问题?是否有一个更好的版本(即更准确,更快或更简洁而不被混淆)?

有许多与其他语言有关的帖子,但是我似乎找不到ECMAScript的权威版本。


Answers:


378

使用模数:

function isEven(n) {
   return n % 2 == 0;
}

function isOdd(n) {
   return Math.abs(n % 2) == 1;
}

您可以使用以下命令检查Javascript中的任何值是否可以强制转换为数字:

Number.isFinite(parseFloat(n))

此检查最好应在isEvenisOdd函数外部进行,这样您就不必在两个函数中重复进行错误处理。


@Steve是的,但是JS在value不是数字或什至是数字的情况下会遇到一些特殊问题。例:0.1%2NaN%2[]%2等你的答案写什么,他已经知道了。
Alin Purcaru 2011年

1
0.1NaN可以使用上述功能正常工作。空数组有点痛苦,因为它等于0 ...
Steve Mayne

4
@Alin-我添加了数字检查。当您希望算术函数显式处理其他数据类型时,我不确定我能理解这种情况,但是如果这就是OP想要的...
Steve Mayne

2
什么改变return n == parseInt(n);return n === parseInt(n);
JiminP 2011年

2
我认为我在某处阅读了n % 2 !== 0检查奇数时应检查的内容,因为根据语言,它不一定是1。编辑:啊,那是.abs电话的目的。没关系。
ptf

82

我更喜欢使用一点测试:

if(i & 1)
{
    // ODD
}
else
{
    // EVEN
}

这将测试是否在第一个位上表示一个奇数。


仅当您知道是一个数字时才有用。非数字应返回未定义的(或可能会引发错误,但未定义似乎是明智的)。
RobG 2014年

3
绝对。对基于2的数学使用模数应该是非法的;)
aceofspades

4
三元:i & 1 == 1 ? console.log("odd") : console.log("even");此外,+ 1用于提高比
特级

14
@Jacksonkr请注意,JavaScript中没有“位级效率”,因为JavaScript中所有数字都是浮点数,并且使用按位运算符意味着首先将其转换为int,然后执行该操作,然后将其转换回浮点数。

1
@poke正确,它们是Number类型的,但是很高兴知道强类型语言有效率。
罗伯特·布里斯塔

8

接下来呢?我只在IE中进行了测试,但是很高兴能够处理表示任意长度的数字的字符串,实际数字是整数或浮点数,并且在传递布尔,未定义,空值,数组或对象时,两个函数均返回false。(由您决定是否要在传入字符串时忽略前导空格或尾随空格-我假设它们不会被忽略,并且会导致两个函数都返回false。)

function isEven(n) {
   return /^-?\d*[02468]$/.test(n);
}

function isOdd(n) {
   return /^-?\d*[13579]$/.test(n);
}

2
对于我的实现,isEven(2.122e3)返回true,但是isEven(“ 2.122e3”)返回false。相反,我的isEven()不能用于真正的大数字,因为JS在将其转换为用于正则表达式测试的字符串时,将它们以指数格式放置。那好吧。
nnnnnn

@MartijnScheffer-随意将您需要购买的所有额外内存的账单发送给我。请注意,问题确实包括从其他类型到数字的转换,很明显,我在这里建议的要点是要有一个简单的单行函数来处理数字字符串。当然,根据我自己的评论,这实际上并不能解决所有可能的情况,但它仍然可能有用-regex是验证用户输入数据的最简单方法,该方法最初是字符串。
nnnnnn

我在这里发表评论了吗?我没有看到它,但是我可以,如果您想要一个,那不是正确的解决方案,它慢了数百倍,如果您要检查字符串是否有效,我们正在谈论数字而不是字符串数字,以及可以分开处理的整数。
Martijn Scheffer

@MartijnScheffer-是的,您的评论似乎在我回复后的某个时候被删除了。请注意,问题不仅在于数字,OP的代码还包括其他类型的转换。无论如何,感谢您的反馈。
nnnnnn

7

注意:也有负数。

function isOddInteger(n)
{
   return isInteger(n) && (n % 2 !== 0);
}

哪里

function isInteger(n)
{
   return n === parseInt(n, 10);
}

1
parseInt在这里不需要基数吗?
blablabla

@blablabla是,不是所有的实施方式中假设的基数= 10
罗德里戈

良好引用负值。Robert Brisita的答案(稍后添加)也涵盖了这一点。
杰克逊(Jacksonkr)

4

为什么不这样做:

    function oddOrEven(num){
        if(num % 2 == 0)
            return "even";
        return "odd";
    }
    oddOrEven(num);

甚至function isEven(num) { return num % 2 == 0}
chiapa

3
或使用ES6:const oddOrEven = num => num % 2 === 0 ? 'even' : 'odd'
enguerran


1
var isEven = function(number) {
    // Your code goes here!
    if (number % 2 == 0){
       return(true);
    }
    else{
       return(false);    
    }
};

2
if ( <expression> ) return true else return false示例,可以总是被简化为return ( <expression> )(因为在表达if 已经始终是一个布尔值之一)。
Gerold Broser

说return不是函数,就像说如果不是函数,则在返回值时使用括号是完全有效的(即使它们在这里没有用)
Martijn Scheffer

1

史蒂夫·梅恩答案的简单修改/改进!

function isEvenOrOdd(n){
    if(n === parseFloat(n)){
        return isNumber(n) && (n % 2 == 0);
    }
    return false;
}

注意:如果无效,则返回false!


1

为此,我们只需要一行代码!

这是一种更新的替代方法,对JS函数使用新的ES6语法,对if-else语句调用使用单行语法

const isEven = num => ((num % 2) == 0) ? true : false;

alert(isEven(8));  //true
alert(isEven(9));  //false
alert(isEven(-8)); //true

1
简称为let isEven = num => num % 2 === 0。:-)但实际上,这里的许多其他答案没有什么不同。
RobG

1

一些

x % 2 == 0; // Check if even

!(x & 1); // bitmask the value with 1 then invert.

((x >> 1) << 1) == x; // divide value by 2 then multiply again and check against original value

~x&1; // flip the bits and bitmask

0

不同的方式:

var isEven = function(number) {
  // Your code goes here!
  if (((number/2) - Math.floor(number/2)) === 0) {return true;} else {return false;};
};

isEven(69)

0

否则使用字符串,因为为什么不

function isEven(__num){
    return String(__num/2).indexOf('.') === -1;
}

0
if (testNum == 0);
else if (testNum % 2  == 0);
else if ((testNum % 2) != 0 );

没有解释,您的贡献没有太大价值。它还重复讨论中已经介绍的信息。
辛迪·梅斯特

谢谢辛迪!只是提供解决方案!
林赛

但是...这实际上没有任何作用。它不应该返回一些东西吗?
nnnnnn

0

也许这个吗?if(我们的数字%2!== 0)


2
尽管此代码段可以解决问题,但提供说明确实有助于提高您的帖子质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。也请尽量不要在代码中加入解释性注释,这会降低代码和解释的可读性!
Filnor

0
var num = someNumber
    isEven;
parseInt(num/2) === num/2 ? isEven = true : isEven = false;

0

for(var a=0; a<=20;a++){
   if(a%2!==0){
       console.log("Odd number "+a);
   }
}

for(var b=0; b<=20;a++){
    if(b%2===0){
        console.log("Even number "+b);  
    }     
 }


尽管这段代码可以解决问题,但包括解释如何以及为什么解决该问题的说明,确实可以帮助提高您的帖子质量,并可能导致更多的投票。请记住,您将来会为读者回答问题,而不仅仅是现在问的人。请编辑您的答案以添加说明,并指出适用的限制和假设。
Xnero

0
var isOdd = x => Boolean(x % 2);
var isEven = x => !isOdd(x);

-1

要测试您是否有奇数或偶数,这也可以。

const comapare = x => integer(checkNumber(x));

function checkNumber (x) {
   if (x % 2 == 0) {
       return true;
   } 
   else if (x % 2 != 0) {
       return false;
    }
}

function integer (x) {
   if (x) {
       console.log('even');
   } 
   else {
       console.log('odd');
    }
}

-1

使用现代的javascript样式:

const NUMBERS = "nul one two three four five six seven ocho nueve".split(" ")

const isOdd  = n=> NUMBERS[n % 10].indexOf("e")!=-1
const isEven = n=> isOdd(+n+1)

isOdd('5'))返回true。isEven('5')也返回true。isOdd(NaN)引发错误。:-(
RobG '17年

固定的isEven('5')isOdd(NaN)可能应该抛出一个错误。
冈恩

1
脚本宿主不应该处理错误,函数应该。我总是被告知核心转储不是正常的终止。;-)
RobG


-2
function isEven(n) {return parseInt(n)%2===0?true:parseInt(n)===0?true:false}

当0 /甚至想要但

isEven(0) //true
isEven(1) //false
isEven(2) //true
isEven(142856) //true
isEven(142856.142857)//true
isEven(142857.1457)//false


或者return parseInt(n)%2===0?true:parseInt(n)===0。但是话又说回来,这与这里已经存在的许多其他答案相同。
异端猴子

1
或者return parseInt(n)%2 === 0 || parseInt(n) === 0。但是为什么要parseInt呢?对于像“ 32foo”和这样的值不相等的值12.5,它将返回true 。
RobG

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.