测试一个值是奇数还是偶数

IT技术 javascript numbers
2021-02-04 08:32:06

我决定用一个非常简单的算法创建简单的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 的最终版本。

6个回答

使用模数:

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

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

您可以检查是否可以将 Javascript 中的任何值强制转换为数字:

Number.isFinite(parseFloat(n))

此检查最好在isEvenisOdd函数之外完成,因此您不必在两个函数中重复错误处理。

0.1NaN使用上述功能正常工作。空数组有点麻烦,因为它等于 0...
2021-03-14 08:32:06
@Alin - 我添加了一个数字检查。当您希望算术函数显式处理其他数据类型时,我不确定我是否理解这种情况,但如果这是 OP 想要的......
2021-03-22 08:32:06
@Andy Ray - 你不能对 isOdd 说 !isEven(number) ,因为这意味着 0.1 是奇数,因为它不是偶数。
2021-03-22 08:32:06
什么改变return n == parseInt(n);return n === parseInt(n);
2021-03-24 08:32:06
我想我在某处阅读了n % 2 !== 0检查奇数时应该检查的内容,因为它不一定是 1,具体取决于语言。编辑:啊,这就是.abs电话的目的。没关系。
2021-04-07 08:32:06

我更喜欢使用一点测试:

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

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

@AndrewCastellano 您正在测试单个位,而不是 i 的整个值。任何大于 0 的数字都是真的,但这并不意味着它是奇数或偶数。查看:bitwisecmd.com并根据输入的数字查看位的扩展。
2021-03-13 08:32:06
绝对地。对基数为 2 的数学使用模数应该是非法的;)
2021-03-21 08:32:06
三元:i & 1 == 1 ? console.log("odd") : console.log("even");此外,位级效率 +1(在 JS 中没有广泛使用)
2021-03-26 08:32:06
@Jacksonkr 请注意,JavaScript 中没有“位级效率”,因为 JavaScript 中的所有数字都是浮点数,使用按位运算符意味着首先将其转换为 int,然后执行操作,然后将其转换回浮点数。
2021-04-02 08:32:06
@poke 正确,它们属于 Number 类型,但很高兴知道强类型语言具有效率。
2021-04-02 08:32:06

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

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

function isOdd(n) {
   return /^-?\d*[13579]$/.test(n);
}
@MartijnScheffer - 请随时向我发送您必须购买的所有额外内存的账单。请注意,该问题确实包括从其他类型到数字的转换,显然我在这里建议的重点是使用一个简单的单行函数来处理数字字符串。当然,根据我自己的评论,这实际上并没有处理所有可能的情况,但它仍然可能有用 - 正则表达式是验证用户输入数据的最简单方法,最初将是一个字符串。
2021-03-21 08:32:06
@MartijnScheffer - 是的,您有评论,自我回复以来似乎已被删除。请注意,问题不仅与数字有关,OP 的代码还包括来自其他类型的转换。无论如何,感谢您的反馈。
2021-03-28 08:32:06
对于我的实现, isEven(2.122e3) 返回 true,但 isEven("2.122e3") 返回 false。相反,我的 isEven() 对于非常大的数字失败,因为 JS 在为正则表达式测试转换为字符串时将它们置于指数格式中。那好吧。
2021-03-29 08:32:06
我在这里发表评论了吗?我没有看到,但是如果你想要一个我可以number 和一个可以单独处理的整数。
2021-04-10 08:32:06

注意:也有负数。

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

在哪里

function isInteger(n)
{
   return n === parseInt(n, 10);
}
很好地引用了负值。Robert Brisita 的回答(稍后添加)也涵盖了这一点。
2021-03-17 08:32:06
@blablabla 是的,并非所有实现都假定基数 = 10。
2021-03-28 08:32:06
parseInt 在这里不需要基数吗?
2021-04-03 08:32:06

为什么不这样做:

    function oddOrEven(num){
        if(num % 2 == 0)
            return "even";
        return "odd";
    }
    oddOrEven(num);
或使用 ES6: const oddOrEven = num => num % 2 === 0 ? 'even' : 'odd'
2021-03-16 08:32:06
甚至function isEven(num) { return num % 2 == 0}
2021-04-07 08:32:06