値が奇数か偶数かをテストする


173

非常に単純なアルゴリズムを使用して、単純なisEvenおよびisOdd関数を作成することにしました。

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の決定版を見つけることができないようです。


回答:


368

係数を使用:

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数値でない場合、または数値であっても、JSにはいくつかの特別な問題があります。例:0.1%2NaN%2[]%2、などあなたが答えに書いた何を、彼はすでにそれを知っています。
Alin Purcaru、2011年

1
0.1そしてNaN上記の機能を備えた作業罰金。空の配列は0に相当するため、少々苦痛です...
Steve Mayne

4
@Alin-数値チェックを追加しました。算術関数で他のデータ型を明示的に処理する必要がある場合のシナリオを理解しているとは思いませんが、それがOPで必要なものである場合...
Steve Mayne

2
に変更return n == parseInt(n);するのはreturn n === parseInt(n);どうですか?
JiminP

2
n % 2 !== 0奇数をチェックするときにチェックすべきことをどこかで読んだと思います。言語によっては1とは限らないからです。編集:ああ、それが.abs呼びかけの目的です。じゃあ心配しないで。
ptf

78

私はビットテストを使用することを好みます:

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

これは、奇数を意味する最初のビットがオンであるかどうかをテストします。


が最初の数だとわかっている場合にのみ役立ちます。非数値は未定義を返す必要があります(またはエラーをスローする可能性がありますが、未定義は賢明なようです)。
RobG 2014年

3
もちろんです。base-2数学に係数を使用することは違法であるべきです;)
aceofspades

4
Ternary:i & 1 == 1 ? console.log("odd") : console.log("even");また、ビットレベル効率の+1(JSでは
それほど

13
@Jacksonkr JavaScriptでは「ビットレベルの効率」はないことに注意してください。すべての数値はJavaScriptで浮動小数点数であり、ビットごとの演算子を使用することは、最初にそれをintに変換し、次に操作を実行してから、浮動小数点数に戻すことを意味します。
突く

1
@poke正しいNumber型ですが、強く型付けされた言語には効率があることを知っておくのは良いことです。
Robert Brisita 2017

8

次はどうですか?私はこれをIEでのみテストしましたが、任意の長さの数値を表す文字列、整数または浮動小数点数である実際の数値を処理することは非常に満足であり、ブール、未定義、null、配列またはオブジェクトが渡されると、両方の関数が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を返します。逆に、正規表現テストで文字列に変換するときにJSが指数形式でそれらを配置するため、非常に大きな数値に対してはisEven()が失敗します。しかたがない。
nnnnnn

@MartijnScheffer-購入する必要のある余分なメモリすべての請求書を送ってください。質問には他の型から数値への変換が含まれていたことに注意してください。ここで私が提案していることのポイントは、数値文字列を処理する単純な1行の関数を持つことです。もちろん、私自身のコメントによると、これは実際にはすべての可能性のあるケースを処理するわけではありませんが、それでも有用かもしれません-正規表現は、ユーザーが入力したデータを検証する最も簡単な方法です。
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 2015年

@blablablaはい、すべての実装が想定基数= 10
Rodrigoの

負の値の良い引用。Robert Brisitaの回答(後で追加)もこれをカバーしています。
Jacksonkr

4

なぜこれをしないのですか?

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

またはfunction isEven(num) { return num % 2 == 0}
チアパ

3
またはES6の場合:const oddOrEven = num => num % 2 === 0 ? 'even' : 'odd'
enguerran 2018年


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 2017

returnが関数ではないことを言うのは、が関数ではない場合、値を返すときに括弧を使用することは完全に有効です(ここでは役に立たなくても)
Martijn Scheffer

1

Steve Mayneの回答の簡単な修正/改善!

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

注:無効な場合はfalseを返します。


1

このために必要なコードは1行だけです。

JS関数に新しいES6構文を使用し、ステートメント呼び出しに1行の構文を使用する、これを行うための新しい代替方法を次に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 );

説明がなければ、あなたの貢献はあまり価値がありません。また、ディスカッションですでに提示されている情報も繰り返します。
Cindy Meister

シンディありがとう!ソリューションを提供するだけです!
リンゼイ

しかし...これは実際に何もしません。それは何かを返すべきではありませんか?
nnnnnn 2016年

0

多分これ?if(ourNumber%2!== 0)


2
このコードスニペットは質問を解決する可能性がありますが、説明を含めると、投稿の品質を向上させるのに役立ちます。あなたは将来の読者のための質問に答えていることを覚えておいてください、そしてそれらの人々はあなたのコード提案の理由を知らないかもしれません。また、コードを説明コメントで混雑させないようにしてください。これにより、コードと説明の両方が読みにくくなります。
Filnor 2018年

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);  
    }     
 }


このコードは問題を解決する可能性がありますが、これが問題を解決する方法と理由の説明含めると、投稿の品質が向上し、おそらくより多くの投票が得られます。あなたが今尋ねている人だけでなく、あなたが将来の読者のための質問に答えていることを忘れないでください。回答を編集して説明を追加し、適用される制限と前提を示してください。
Daniil

-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 2017年

固定isEven('5')isOdd(NaN)おそらくエラーをスローするはずです。
ガン

1
スクリプトホストはエラーを処理するべきではなく、関数は処理するべきです。コアダンプは正常な終了ではないといつも言われていました。;-)
RobG 2017年

-2

これはもっと簡単です!

  var num = 3 //instead get your value here
  var aa = ["Even", "Odd"];

  alert(aa[num % 2]);

1
それは未定義で返されますnum = -1
Linus Oleander

-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」やのような値でtrueを返します12.5
RobG

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.