测试值是奇数还是偶数

Rob*_*obG 159 javascript numbers

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

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

function isOdd(n) {
  return isEven(Number(n) + 1);
}
Run Code Online (Sandbox Code Playgroud)

如果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));
Run Code Online (Sandbox Code Playgroud)

任何人都可以看到上述问题吗?是否有更好的(即更准确,更快速或更简洁而不被混淆)版本?

有各种与其他语言相关的帖子,但我似乎找不到ECMAScript的最终版本.

编辑

添加了代码审核标记,但我不是在进行代码审核之后.我简单地发布了代码,以便其他人可以看到我在哪里,而不是要审查的东西.到目前为止发布的答案似乎得到了.

编辑2

最终的功能,基于史蒂夫的回答:

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

function isOdd(n) {
  return isEven(Number(n) + 1);
}
Run Code Online (Sandbox Code Playgroud)

任何不是数字的东西都返回undefined,数字返回truefalse.它可能是一个带有严格标志的函数,但我认为严格的比较并不是真正需要的.

Ste*_*yne 335

使用模数:

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

function isOdd(n) {
   return Math.abs(n % 2) == 1;
}
Run Code Online (Sandbox Code Playgroud)

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

Number.isFinite(parseFloat(n))
Run Code Online (Sandbox Code Playgroud)

此检查最好在函数isEvenisOdd函数之外进行,因此您不必在两个函数中复制错误处理.

  • @Alin - 我添加了一个数字检查.当你想要一个算术函数来显式处理其他数据类型时,我不确定我是否理解这个场景,但如果那是OP想要的...... (3认同)
  • `0.1` 和 `NaN` 与上面的函数配合得很好。空数组有点麻烦,因为它等于 0... (2认同)
  • 怎么样改变`return n == parseInt(n);`到`return n === parseInt(n);`? (2认同)
  • 我想我在检查奇数时应该检查`n%2!== 0`,因为它不一定是1,这取决于语言.编辑:啊,这就是`.abs`调用的内容.没关系. (2认同)
  • @Andy Ray - 你不能为 isOdd 说 !isEven(number) ,因为这意味着 0.1 是奇数,因为它不是偶数。 (2认同)

Rob*_*ita 74

我更喜欢使用一点测试:

if(i & 1)
{
    // ODD
}
else
{
    // EVEN
}
Run Code Online (Sandbox Code Playgroud)

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

  • @Jacksonkr请注意,JavaScript中没有"位级效率",因为所有数字都是JavaScript中的浮点数,使用按位运算符意味着首先将其转换为int,然后执行操作,然后将其转换回浮点数. (10认同)
  • 三元:'我和1 == 1?console.log("odd"):console.log("even");`此外,+1用于位级效率(不是在JS中广泛使用) (4认同)
  • 绝对.使用模数进行base-2数学运算应该是非法的;) (3认同)

Ivo*_*ema 7

注意:还有负数.

function isOddInteger(n)
{
   return isInteger(n) && (n % 2 !== 0);
}
Run Code Online (Sandbox Code Playgroud)

哪里

function isInteger(n)
{
   return n === parseInt(n, 10);
}
Run Code Online (Sandbox Code Playgroud)


nnn*_*nnn 6

以下怎么样?我只在IE中对此进行了测试,但是很乐意处理表示任意长度数字的字符串,实际数字是整数或浮点数,并且当传递布尔值,未定义,null,数组或对象时,这两个函数都返回false.(在传入字符串时,是否要忽略前​​导或尾随空白取决于您 - 我假设它们不会被忽略并导致两个函数都返回false.)

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

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

  • 对于我的实现,isEven(2.122e3)返回true,但isEven("2.122e3")返回false.相反,我的isEven()因为非常大的数字而失败,因为JS在转换为字符串进行正则表达式测试时将它们置于指数格式中.那好吧. (2认同)

小智 5

完成罗伯特·布里西塔的位测试。

if ( ~i & 1 ) {
    // Even
}
Run Code Online (Sandbox Code Playgroud)


baz*_*baz 5

var isOdd = x => Boolean(x % 2);
var isEven = x => !isOdd(x);
Run Code Online (Sandbox Code Playgroud)