Kiểm tra xem một giá trị là lẻ hay chẵn


173

Tôi quyết định tạo hàm isEvenisOdd đơn giản với thuật toán rất đơn giản:

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

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

Điều đó là ổn nếu n với một số tham số nhất định, nhưng thất bại trong nhiều tình huống. Vì vậy, tôi đã đặt ra để tạo ra các hàm mạnh mẽ mang lại kết quả chính xác cho nhiều kịch bản nhất có thể, để chỉ các số nguyên trong giới hạn của số javascript được kiểm tra, mọi thứ khác đều trả về sai (bao gồm cả + và - vô cùng). Lưu ý rằng số 0 là chẵn.

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

Bất cứ ai có thể nhìn thấy bất kỳ vấn đề với ở trên? Có phiên bản nào tốt hơn (tức là chính xác hơn, nhanh hơn hoặc ngắn gọn hơn mà không bị xáo trộn) không?

Có nhiều bài viết liên quan đến các ngôn ngữ khác, nhưng dường như tôi không thể tìm thấy phiên bản dứt khoát cho ECMAScript.


Câu trả lời:


368

Sử dụng mô đun:

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

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

Bạn có thể kiểm tra xem mọi giá trị trong Javascript có thể bị ép buộc thành một số với:

Number.isFinite(parseFloat(n))

Kiểm tra này tốt nhất nên được thực hiện bên ngoài isEvenvà các isOddchức năng, vì vậy bạn không phải nhân đôi xử lý lỗi trong cả hai chức năng.


@Steve Có, nhưng JS có một số vấn đề đặc biệt khi valuekhông phải là số hoặc ngay cả khi đó là số. Ex .: 0.1%2,NaN%2 , []%2, vv Những gì bạn đã viết trong câu trả lời, anh đã biết điều đó.
Alin Purcaru

1
0.1NaNhoạt động tốt với chức năng trên. Mảng trống là một chút đau đớn vì nó tương đương với 0 ...
Steve Mayne

4
@Alin - Tôi đã thêm một kiểm tra số. Tôi không chắc là tôi hiểu kịch bản khi bạn muốn một hàm số học xử lý rõ ràng các kiểu dữ liệu khác, nhưng nếu đó là điều OP muốn ...
Steve Mayne

2
Thay đổi return n == parseInt(n);thành return n === parseInt(n);gì?
JiminP

2
Tôi nghĩ rằng tôi đã đọc ở đâu đó những gì bạn nên kiểm tra n % 2 !== 0khi kiểm tra các số lẻ, bởi vì nó không nhất thiết là 1, tùy thuộc vào ngôn ngữ. EDIT: Ah, đó là những gì .abscuộc gọi dành cho. Đừng bận tâm.
ptf

78

Tôi thích sử dụng một bài kiểm tra bit:

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

Điều này kiểm tra xem bit đầu tiên nằm trên đó biểu thị một số lẻ.


Chỉ hữu ích nếu bạn biết tôi là một số để bắt đầu. Các số không liên kết sẽ trả về không xác định (hoặc có thể đưa ra lỗi, nhưng không xác định có vẻ hợp lý).
RobG

3
Chắc chắn rồi. Sử dụng mô-đun cho toán cơ sở 2 là bất hợp pháp;)
aceofspades

4
Ternary: i & 1 == 1 ? console.log("odd") : console.log("even");Ngoài ra, +1 cho hiệu quả cấp bit (không được sử dụng rộng rãi trong JS)
Jacksonkr

13
@Jacksonkr Lưu ý rằng JavaScript không có hiệu suất cấp bit bit trong JavaScript vì tất cả các số đều trôi nổi trong JavaScript và sử dụng toán tử bitwise có nghĩa là trước tiên chuyển đổi nó thành int, sau đó thực hiện thao tác và sau đó chuyển đổi lại thành số dấu phẩy động.
chọc

1
@poke Đúng họ thuộc loại Số nhưng thật tuyệt khi biết rằng có hiệu quả trong các ngôn ngữ được gõ mạnh.
Robert Brisita

8

Làm thế nào về sau đây? Tôi chỉ thử nghiệm điều này trong IE, nhưng thật vui khi xử lý các chuỗi đại diện cho các số có độ dài bất kỳ, số thực là số nguyên hoặc số float và cả hai hàm đều trả về false khi truyền một boolean, không xác định, null, một mảng hoặc một đối tượng. (Tùy thuộc vào việc bạn muốn bỏ qua khoảng trống hàng đầu hay dấu kiểm khi chuỗi được truyền vào - Tôi đã giả sử rằng chúng không bị bỏ qua và khiến cả hai hàm trả về sai.)

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

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

2
Đối với triển khai của tôi, isEven (2.122e3) trả về true, nhưng isEven ("2.122e3") trả về false. Ngược lại, isEven () của tôi không thành công cho các số thực sự lớn vì JS đặt chúng ở định dạng số mũ khi chuyển đổi thành chuỗi cho kiểm tra regex. Ồ tốt
nnnnnn

@MartijnScheffer - Vui lòng gửi cho tôi hóa đơn cho tất cả bộ nhớ bổ sung mà bạn sẽ phải mua. Lưu ý rằng câu hỏi đã bao gồm chuyển đổi từ các loại khác sang số và rõ ràng điểm của những gì tôi đề xuất ở đây là có một hàm một dòng đơn giản xử lý số chuỗi. Tất nhiên, theo nhận xét của riêng tôi, điều này thực sự không xử lý tất cả các trường hợp có thể, nhưng nó vẫn có thể hữu ích - regex là cách đơn giản nhất để xác thực dữ liệu do người dùng nhập vào, đây sẽ là một chuỗi ban đầu.
nnnnnn

tôi đã đăng một bình luận ở đây? Tôi không thấy nó, nhưng tôi có thể nếu bạn muốn một cái! số và một số nguyên có thể được xử lý riêng biệt.
Martijn Scheffer

@MartijnScheffer - Vâng, có một nhận xét từ bạn, dường như đã bị xóa tại một số điểm kể từ khi tôi trả lời. Lưu ý rằng câu hỏi không chỉ về số, mã của OP bao gồm chuyển đổi từ các loại khác. Dù sao, cảm ơn phản hồi của bạn.
nnnnnn

7

Lưu ý: cũng có số âm.

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

Ở đâu

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

1
Không parseInt không cần một cơ số ở đây?
blablabla

@blablabla Có, không phải tất cả các triển khai đều giả sử radix = 10.
Rodrigo

Trích dẫn tốt các giá trị tiêu cực. Câu trả lời của Robert Brisita (đã được thêm vào sau) cũng bao gồm điều này.
Jacksonkr

4

Tại sao không làm điều này:

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

Hoặc thậm chí function isEven(num) { return num % 2 == 0}
chiapa

3
hoặc với ES6:const oddOrEven = num => num % 2 === 0 ? 'even' : 'odd'
Anh

4

Để hoàn thành bài kiểm tra bit của Robert Brisita.

if ( ~i & 1 ) {
    // Even
}

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

2
Các if ( <expression> ) return true else return falsemô hình có thể luôn được đơn giản hóa đến return ( <expression> )(kể từ khi biểu hiện trong một if đã luôn luôn là một trong những boolean).
Gerold Broser

nói rằng trả về không phải là một hàm, giống như nói nếu không phải là một hàm, thì hoàn toàn hợp lệ khi sử dụng dấu ngoặc đơn khi trả về một giá trị (ngay cả khi chúng không hữu ích ở đây)
Martijn Scheffer

1

Một sửa đổi / cải tiến đơn giản của câu trả lời Steve Mayne!

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

Lưu ý: Trả về false nếu không hợp lệ!


1

Chúng tôi chỉ cần một dòng mã cho việc này!

Đây là một cách mới hơn và thay thế để làm điều này, sử dụng cú pháp ES6 mới cho các hàm JS và cú pháp một dòng cho if-elselệnh gọi:

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

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

1
Mà ngắn hơn là let isEven = num => num % 2 === 0. :-) Nhưng thực sự nó không khác với nhiều câu trả lời khác ở đây.
RobG

1

Một vài

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

Cách khác:

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

isEven(69)

0

Mặt khác sử dụng chuỗi vì tại sao không

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

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

Không có lời giải thích đóng góp của bạn không có nhiều giá trị. Nó cũng lặp lại thông tin đã được trình bày trong cuộc thảo luận.
Cindy Meister

Cảm ơn Cindy! Chỉ cần cung cấp một giải pháp!
Lindsay

Nhưng ... điều này thực sự không làm gì cả. Nó có nên trả lại cái gì không?
nnnnnn

0

Có lẽ điều này? if (ourNumber% 2! == 0)


2
Mặc dù đoạn mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn. Xin vui lòng cố gắng không làm đông mã của bạn với các bình luận giải thích, điều này làm giảm khả năng đọc của cả mã và các giải thích!
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);  
    }     
 }


Mặc dù mã này có thể giải quyết câu hỏi, bao gồm giải thích về cách thức và lý do giải quyết vấn đề này thực sự sẽ giúp cải thiện chất lượng bài đăng của bạn và có thể dẫn đến nhiều lượt bình chọn hơn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai, không chỉ người hỏi bây giờ. Vui lòng chỉnh sửa câu trả lời của bạn để thêm giải thích và đưa ra dấu hiệu về những hạn chế và giả định được áp dụng.
Daniil

-1

Để kiểm tra xem bạn có số lẻ hay số chẵn hay không, điều này cũng hoạt động.

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

Sử dụng kiểu javascript hiện đại:

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'))trả về đúng isEven('5')cũng trả về đúng. isOdd(NaN)ném một lỗi. :-(
RobG

Đã sửa isEven('5'). isOdd(NaN)có lẽ nên ném một lỗi.
bắn

1
Máy chủ lưu trữ kịch bản không nên xử lý lỗi, chức năng nên. Tôi luôn luôn nói rằng một bãi rác cốt lõi không phải là một chấm dứt bình thường . ;-)
RobG


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

khi 0 / thậm chí muốn nhưng

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

Hay nói, là một tài tài của, qua, qua, qua một tài khác, qua giữ, qua một tài khác


Hoặc return parseInt(n)%2===0?true:parseInt(n)===0. nhưng sau đó, một lần nữa, điều này giống như nhiều câu trả lời khác đã có ở đây.
Khỉ Heretic

1
Hoặc return parseInt(n)%2 === 0 || parseInt(n) === 0. Nhưng tại sao parseInt ? Điều đó trả về đúng cho các giá trị như "32foo" và 12.5, thậm chí không.
RobG

-2
if (i % 2) {
return odd numbers
}

if (i % 2 - 1) {
return even numbers
}

1
Khi nào thì nhắc nhở chia bất kỳ số nào cho 2 thành 2?
dùng85421

Hừm, bạn có quyền. Tôi nhớ viết% 2 == 2. Cái xấu của tôi.
Dejan Markovic
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.