Menguji apakah suatu nilai ganjil atau genap

173

Saya memutuskan untuk membuat sederhana ISEVEN dan ISODD fungsi dengan algoritma yang sangat sederhana:

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

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

Tidak apa-apa jika n dengan parameter tertentu, tetapi gagal untuk banyak skenario. Jadi saya mulai membuat fungsi yang kuat yang memberikan hasil yang benar untuk sebanyak mungkin skenario, sehingga hanya bilangan bulat dalam batas angka javascript yang diuji, yang lainnya mengembalikan false (termasuk + dan - tak terhingga). Perhatikan bahwa nol adalah genap.

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

Adakah yang bisa melihat masalah dengan hal di atas? Apakah ada versi yang lebih baik (yaitu lebih akurat, lebih cepat atau lebih ringkas tanpa dikaburkan)?

Ada berbagai posting yang berkaitan dengan bahasa lain, tetapi sepertinya saya tidak dapat menemukan versi definitif untuk ECMAScript.

RobG
sumber

Jawaban:

368

Gunakan modulus:

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

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

Anda dapat memeriksa bahwa nilai apa pun dalam Javascript dapat dipaksa ke nomor dengan:

Number.isFinite(parseFloat(n))

Pemeriksaan ini sebaiknya dilakukan di luar fungsi isEvendan isOdd, jadi Anda tidak harus menduplikasi penanganan kesalahan di kedua fungsi.

Steve Mayne
sumber
@Steve Ya, tetapi JS memiliki beberapa masalah khusus ketika valuebukan angka, atau bahkan jika itu angka. Ex .: 0.1%2, NaN%2, []%2, dll Apa yang Anda tulis dalam jawaban, dia sudah tahu itu.
Alin Purcaru
1
0.1dan NaNbekerja dengan baik dengan fungsi di atas. Array kosong sedikit menyebalkan karena sama dengan 0 ...
Steve Mayne
4
@Alin - Saya telah menambahkan cek numerik. Saya tidak yakin saya memahami skenario ketika Anda ingin fungsi aritmatika untuk secara eksplisit menangani tipe data lain, tetapi jika itu yang diinginkan OP ...
Steve Mayne
2
Bagaimana mengubah return n == parseInt(n);ke return n === parseInt(n);?
JiminP
2
Saya pikir saya membaca di suatu tempat apa yang harus Anda periksa n % 2 !== 0ketika memeriksa angka ganjil, karena belum tentu 1, tergantung pada bahasanya. EDIT: Ah, itulah gunanya .abspanggilan itu. Lupakan saja.
ptf
79

Saya lebih suka menggunakan uji bit:

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

Ini menguji apakah bit pertama adalah yang menandakan angka ganjil.

Robert Brisita
sumber
Hanya berguna jika Anda tahu saya adalah nomor untuk memulai. Non-angka harus mengembalikan yang tidak terdefinisi (atau mungkin membuat kesalahan, tetapi undefined tampaknya masuk akal).
RobG
3
Benar. Menggunakan modulus untuk matematika dasar-2 harus ilegal;)
aceofspades
4
Ternary: i & 1 == 1 ? console.log("odd") : console.log("even");Juga, +1 untuk efisiensi level bit (tidak banyak digunakan di JS)
Jacksonkr
13
@Jacksonkr Perhatikan bahwa tidak ada "efisiensi tingkat bit" dalam JavaScript karena semua angka mengapung dalam JavaScript dan menggunakan operator bitwise berarti pertama-tama mengubahnya menjadi int, kemudian melakukan operasi, dan kemudian mengubahnya kembali ke angka floating point.
colok
1
@ Poke Benar mereka bertipe Number tetapi senang mengetahui bahwa ada efisiensi dalam bahasa yang sangat diketik.
Robert Brisita
8

Bagaimana dengan yang berikut ini? Saya hanya menguji ini di IE, tapi itu cukup senang untuk menangani string yang mewakili angka berapa pun panjangnya, angka aktual yang bilangan bulat atau mengapung, dan kedua fungsi mengembalikan false ketika melewati boolean, undefined, null, array atau objek. (Terserah Anda apakah Anda ingin mengabaikan kekosongan awal atau akhir saat string dilewatkan - Saya berasumsi mereka tidak diabaikan dan menyebabkan kedua fungsi mengembalikan false.)

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

function isOdd(n) {
   return /^-?\d*[13579]$/.test(n);
}
nnnnnn
sumber
2
Untuk implementasi saya isEven (2.122e3) mengembalikan true, tetapi isEven ("2.122e3") mengembalikan false. Sebaliknya isEven () saya gagal untuk angka yang sangat besar karena JS menempatkannya dalam format eksponen ketika dikonversi ke string untuk tes regex. Baiklah.
nnnnnn
@ MartijnScheffer - Silakan kirimi saya tagihan untuk semua memori ekstra yang harus Anda beli. Perhatikan bahwa pertanyaannya mencakup konversi dari tipe lain ke angka, dan jelas maksud dari apa yang saya sarankan di sini adalah memiliki fungsi satu baris sederhana yang menangani angka dan string. Tentu saja, sesuai komentar saya sendiri, ini sebenarnya tidak menangani semua kasus yang mungkin, tetapi masih mungkin berguna - regex adalah cara paling sederhana untuk memvalidasi data yang dimasukkan pengguna, yang pada awalnya akan berupa string.
nnnnnn
apakah saya mengirim komentar di sini? saya tidak melihatnya, tetapi saya bisa jika Anda menginginkannya!, ini BUKAN solusi yang benar, ini ratusan kali lebih lambat, dan kita berbicara tentang angka bukan string, jika Anda ingin memeriksa apakah string valid angka, dan bilangan bulat yang dapat ditangani secara terpisah.
Martijn Scheffer
@ MartijnScheffer - Ya, ada komentar dari Anda, tampaknya telah dihapus di beberapa titik sejak balasan saya. Perhatikan bahwa pertanyaannya bukan hanya tentang angka, kode OP termasuk konversi dari jenis lain. Bagaimanapun, terima kasih atas tanggapan Anda.
nnnnnn
7

Catatan: ada juga angka negatif.

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

dimana

function isInteger(n)
{
   return n === parseInt(n, 10);
}
Ivo Renkema
sumber
1
Tidak perlu parseInt perlu radix di sini?
blablabla
@blablabla Ya, tidak semua implementasi menganggap radix = 10.
Rodrigo
Kutipan nilai negatif yang baik. Jawaban Robert Brisita (yang ditambahkan kemudian) mencakup hal ini juga.
Jacksonkr
4

Mengapa tidak lakukan saja ini:

    function oddOrEven(num){
        if(num % 2 == 0)
            return "even";
        return "odd";
    }
    oddOrEven(num);
sandi
sumber
Atau bahkan function isEven(num) { return num % 2 == 0}
chiapa
3
atau dengan ES6:const oddOrEven = num => num % 2 === 0 ? 'even' : 'odd'
enguerran
4

Untuk menyelesaikan tes bit Robert Brisita.

if ( ~i & 1 ) {
    // Even
}
Raoul Kieffer
sumber
1
var isEven = function(number) {
    // Your code goes here!
    if (number % 2 == 0){
       return(true);
    }
    else{
       return(false);    
    }
};
Pandemum
sumber
2
The if ( <expression> ) return true else return falseparadigma dapat selalu disederhanakan return ( <expression> )(karena ekspresi dalam if sudah selalu satu boolean).
Gerold Broser
mengatakan bahwa pengembalian bukanlah fungsi, seperti mengatakan jika bukan fungsi, sangat valid untuk menggunakan tanda kurung ketika mengembalikan nilai (bahkan jika mereka tidak berguna di sini)
Martijn Scheffer
1

Modifikasi / peningkatan sederhana jawaban Steve Mayne!

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

Catatan: Mengembalikan nilai false jika tidak valid!

Eduardo Lucio
sumber
1

Kami hanya perlu satu baris kode untuk ini!

Di sini cara yang lebih baru dan alternatif untuk melakukan ini, menggunakan sintaks ES6 baru untuk fungsi JS, dan sintaks satu baris untuk if-elsepanggilan pernyataan:

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

alert(isEven(8));  //true
alert(isEven(9));  //false
alert(isEven(-8)); //true
Fellipe Sanches
sumber
1
Yang lebih pendek sebagai let isEven = num => num % 2 === 0. :-) Tapi sebenarnya tidak ada bedanya dengan banyak jawaban lain di sini.
RobG
1

Beberapa

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
Kosong
sumber
0

Cara yang berbeda:

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

isEven(69)
grizmin
sumber
0

Otherway menggunakan string karena mengapa tidak

function isEven(__num){
    return String(__num/2).indexOf('.') === -1;
}
Eric
sumber
0
if (testNum == 0);
else if (testNum % 2  == 0);
else if ((testNum % 2) != 0 );
Lindsay
sumber
Tanpa penjelasan, kontribusi Anda tidak memiliki banyak nilai. Itu juga mengulangi informasi yang telah disajikan dalam diskusi.
Cindy Meister
Terima kasih Cindy! Hanya menawarkan solusi!
Lindsay
Tapi ... ini sebenarnya tidak melakukan apa - apa. Bukankah seharusnya mengembalikan sesuatu?
nnnnnn
0

Mungkin ini? if (ourNumber% 2! == 0)

gavr1loo
sumber
2
Sementara potongan kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan sangat membantu untuk meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, dan orang-orang itu mungkin tidak tahu alasan untuk saran kode Anda. Tolong juga cobalah untuk tidak membuat kerumunan kode Anda dengan komentar penjelasan, ini mengurangi keterbacaan kode dan penjelasan!
Filnor
0
var num = someNumber
    isEven;
parseInt(num/2) === num/2 ? isEven = true : isEven = false;
Nelles
sumber
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);  
    }     
 }

Hamza Ali
sumber
Sementara kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan tentang bagaimana dan mengapa ini menyelesaikan masalah akan sangat membantu untuk meningkatkan kualitas posting Anda, dan mungkin menghasilkan lebih banyak suara. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, bukan hanya orang yang bertanya sekarang. Harap edit jawaban Anda untuk menambahkan penjelasan dan berikan indikasi tentang batasan dan asumsi apa yang berlaku.
Daniil
-1

Untuk menguji apakah Anda memiliki nomor ganjil atau genap, ini juga berfungsi.

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');
    }
}
Siop
sumber
-1

Menggunakan gaya javascript modern:

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)
senjata
sumber
isOdd('5'))mengembalikan true. isEven('5')juga mengembalikan true. isOdd(NaN)melempar kesalahan. :-(
RobG
Tetap isEven('5'). isOdd(NaN)mungkin harus membuang kesalahan.
tembak
1
Host skrip seharusnya tidak menangani kesalahan, fungsinya seharusnya. Saya selalu diberitahu bahwa dump inti bukan penghentian normal . ;-)
RobG
-2

Yang ini lebih sederhana!

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

  alert(aa[num % 2]);
AndroidManifester
sumber
1
Itu akan kembali tidak ditentukan untuknum = -1
Linus Oleander
-2
function isEven(n) {return parseInt(n)%2===0?true:parseInt(n)===0?true:false}

ketika 0 / bahkan ingin tetapi

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

chris188
sumber
Atau return parseInt(n)%2===0?true:parseInt(n)===0. tetapi sekali lagi, ini sama dengan banyak jawaban lain yang sudah ada di sini.
Bidah Monyet
1
Atau return parseInt(n)%2 === 0 || parseInt(n) === 0. Tapi mengapa parseInt ? Yang mengembalikan nilai true seperti "32foo" dan 12.5, yang bahkan tidak.
RobG
-2
if (i % 2) {
return odd numbers
}

if (i % 2 - 1) {
return even numbers
}
Dejan Markovic
sumber
1
kapan pengingat membagi angka dengan 2 menjadi 2?
user85421
Hm, ya, Anda benar. Saya rindu menulis% 2 == 2. Buruk saya.
Dejan Markovic