Проверка, является ли значение нечетным или четным

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.

RobG
источник

Ответы:

368

Используйте модуль:

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

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

Вы можете проверить, что любое значение в Javascript может быть приведено к числу с помощью:

Number.isFinite(parseFloat(n))

Эта проверка должна быть предпочтительно сделана вне isEvenи isOddфункций, так что вам не придется дублировать обработку ошибок в обеих функциях.

Стив Мейн
источник
@ Стив Да, но у JS есть некоторые особые проблемы, когда valueэто не число, или даже если это число. Напр .: 0.1%2, NaN%2, []%2и т.д. То , что вы написали в ответ, он уже знает.
Алин Пуркару
1
0.1и NaNнормально работать с функцией выше. Пустой массив - это немного больно, так как он равен 0 ...
Стив Мэйн,
4
@Alin - я добавил числовую проверку. Я не уверен, что понимаю сценарий, когда вы хотите, чтобы арифметическая функция явно обрабатывала другие типы данных, но если это то, чего хочет ОП ...
Стив Мэйн,
2
Как насчет перехода return n == parseInt(n);на return n === parseInt(n);?
JiminP
2
Я думаю, что где-то прочитал, что вы должны проверить n % 2 !== 0при проверке нечетных чисел, потому что это не обязательно 1, в зависимости от языка. РЕДАКТИРОВАТЬ: Ах, это то, для чего .absпризыв. Тогда не важно.
ПТФ
80

Я предпочитаю использовать немного теста:

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

Это проверяет, включен ли первый бит, который обозначает нечетное число.

Роберт Брисита
источник
Полезно, только если вы знаете, что я номер, с которого нужно начать. Номера не должны возвращать неопределенное (или может выдать ошибку, но неопределенное кажется разумным).
RobG
3
Абсолютно. Использование модуля для математики по основанию 2 должно быть незаконным;)
aceofspades
4
Тройной: i & 1 == 1 ? console.log("odd") : console.log("even");также +1 для эффективности на уровне битов (не так широко используется в JS)
Jacksonkr
13
@Jacksonkr Обратите внимание, что в JavaScript не существует «эффективности на уровне битов», поскольку все числа являются числами с плавающей точкой в ​​JavaScript, и использование побитового оператора означает сначала преобразование его в целое число, затем выполнение операции, а затем преобразование обратно в число с плавающей запятой.
совать
1
@poke Правильно, они относятся к типу Number, но приятно знать, что в строго типизированных языках есть эффективность.
Роберт Брисита
8

Как насчет следующего? Я проверял это только в IE, но он был очень рад обрабатывать строки, представляющие числа любой длины, действительные числа, которые были целыми числами или числами с плавающей запятой, и обе функции возвращали false, когда передали логическое значение, undefined, null, массив или объект. (До вас, хотите ли вы игнорировать начальные или конечные пробелы при передаче строки - я предположил, что они не игнорируются и заставляют обе функции возвращать false.)

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

function isOdd(n) {
   return /^-?\d*[13579]$/.test(n);
}
NNNNNN
источник
2
Для моей реализации isEven (2.122e3) возвращает true, но isEven ("2.122e3") возвращает false. И наоборот, my isEven () не работает для действительно больших чисел, потому что JS помещает их в формат экспоненты при преобразовании в строку для теста регулярных выражений. Ну что ж.
nnnnnn
@MartijnScheffer - не стесняйтесь, присылайте мне счет за всю эту дополнительную память, которую вам придется купить. Обратите внимание, что вопрос включал преобразования из других типов в числа, и ясно, что смысл, который я предлагаю здесь, заключается в том, чтобы иметь простую однострочную функцию, которая обрабатывает числа и строки. Конечно, согласно моему собственному комментарию, это на самом деле не обрабатывает все возможные случаи, но все же может быть полезно - регулярное выражение является самым простым способом проверки введенных пользователем данных, которые изначально будут строкой.
nnnnnn
я оставил комментарий здесь? я не вижу этого, но я могу, если вы хотите один!, это НЕ правильное решение, это в сотни раз медленнее, и мы говорим о числах, а не о строках, если вы хотите проверить, является ли строка действительной число и целое число, которое может обрабатываться отдельно.
Мартин Шеффер
@MartijnScheffer - Да, от вас был комментарий, который, кажется, был удален в какой-то момент после моего ответа. Обратите внимание, что вопрос был не только о числах, код ОП включал преобразования из других типов. В любом случае, спасибо за ваш отзыв.
nnnnnn
7

Примечание: есть и отрицательные числа.

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

где

function isInteger(n)
{
   return n === parseInt(n, 10);
}
Иво Ренкема
источник
1
Разве здесь не нужен анализ?
Blablabla
@blablabla Да, не во всех реализациях предполагается, что radix = 10.
Rodrigo
Хорошее цитирование отрицательных значений. Ответ Роберта Бриситы (который был добавлен позже) также охватывает это.
Джексонкр
4

Почему бы просто не сделать это:

    function oddOrEven(num){
        if(num % 2 == 0)
            return "even";
        return "odd";
    }
    oddOrEven(num);
шифровать
источник
Или даже function isEven(num) { return num % 2 == 0}
Chiapa
3
или с ES6:const oddOrEven = num => num % 2 === 0 ? 'even' : 'odd'
enguerran
4

Чтобы завершить битовый тест Роберта Бриситы

if ( ~i & 1 ) {
    // Even
}
Рауль Киффер
источник
1
var isEven = function(number) {
    // Your code goes here!
    if (number % 2 == 0){
       return(true);
    }
    else{
       return(false);    
    }
};
Pandemum
источник
2
if ( <expression> ) return true else return falseПарадигма может всегда быть упрощена return ( <expression> )(поскольку выражение в if уже всегда булева один).
Герольд Брозер
сказать, что return не является функцией, это все равно, что сказать, что если функция не является функцией, то при возврате значения вполне допустимо использовать круглые скобки (даже если они здесь бесполезны)
Martijn Scheffer
1

Простая модификация / улучшение ответа Стива Мейна!

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

Примечание: возвращает false, если недействительно!

Эдуардо Лучио
источник
1

Нам просто нужна одна строка кода для этого!

Вот более новый и альтернативный способ сделать это, используя новый синтаксис ES6 для функций JS и однострочный синтаксис для if-elseвызова оператора:

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

alert(isEven(8));  //true
alert(isEven(9));  //false
alert(isEven(-8)); //true
Fellipe Sanches
источник
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)
grizmin
источник
0

В противном случае использовать строки, потому что почему бы и нет

function isEven(__num){
    return String(__num/2).indexOf('.') === -1;
}
Эрик
источник
0
if (testNum == 0);
else if (testNum % 2  == 0);
else if ((testNum % 2) != 0 );
Линдсей
источник
Без объяснения причин ваш вклад не имеет большого значения. Также повторяется информация, которая уже была представлена ​​в обсуждении.
Синди Мейстер
Спасибо Синди! Просто предлагая решение!
Линдсей
Но ... это на самом деле ничего не делает . Разве это не должно что-то возвращать?
nnnnnn
0

Может быть, это? if (ourNumber% 2! == 0)

gavr1loo
источник
2
Хотя этот фрагмент кода может решить вопрос, в том числе объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете код. Также постарайтесь не переполнять ваш код пояснительными комментариями, это снижает удобочитаемость кода и пояснений!
Филнор
0
var num = someNumber
    isEven;
parseInt(num/2) === num/2 ? isEven = true : isEven = false;
Nelles
источник
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);  
    }     
 }

Хамза али
источник
Хотя этот код может решить вопрос, в том числе объяснение того, как и почему это решает проблему, действительно поможет улучшить качество вашего сообщения и, вероятно, получит больше голосов "за". Помните, что вы отвечаете на вопрос для читателей в будущем, а не только для того, кто спрашивает сейчас. Пожалуйста, отредактируйте свой ответ, чтобы добавить объяснения и указать, какие ограничения и предположения применяются.
Даниил
-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');
    }
}
SIOP
источник
-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'))возвращает истину. isEven('5')также возвращает истину. isOdd(NaN)выдает ошибку. :-(
RobG
Исправлено isEven('5'). isOdd(NaN)наверное стоит сгенерировать ошибку.
Ганна
1
Хост скрипта не должен обрабатывать ошибку, функция должна. Мне всегда говорили, что дамп ядра не является нормальным завершением . ;-)
RobG
-2

Этот более простой!

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

  alert(aa[num % 2]);
AndroidManifester
источник
1
Это будет возвращаться неопределенным дляnum = -1
Линус Олеандр
-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

chris188
источник
Или return parseInt(n)%2===0?true:parseInt(n)===0. но опять же, это то же самое, что и многие другие ответы уже здесь.
Еретик Обезьяна
1
Или return parseInt(n)%2 === 0 || parseInt(n) === 0. Но почему parseInt ? Это возвращает true для значений типа «32foo» и 12.5, которые не являются четными.
RobG
-2
if (i % 2) {
return odd numbers
}

if (i % 2 - 1) {
return even numbers
}
Деян Маркович
источник
1
когда напоминание о делении любого числа на 2 будет 2?
user85421
Хм, да, ты имеешь право. Я скучаю, пишу% 2 == 2. Мой плохой.
Деян Маркович