Как проверить, является ли целое число четным или нечетным?

Как я могу проверить, является ли данное число четным или нечетным в C?

вопрос задан 2.10.2008
chustar
5854 репутация

31 ответов


  • 450 рейтинг

    Используйте оператор по модулю (%), чтобы проверить, есть ли остаток при делении на 2:

    if (x % 2) { /* x is odd */ }
    

    Несколько человек раскритиковали мой ответ выше, заявив, что используя x & amp; 1 «быстрее» или «эффективнее». Я не верю, что это так.

    Из любопытства я создал две тривиальные тестовые программы:

    /* modulo.c */
    #include 
    
    int main(void)
    {
        int x;
        for (x = 0; x < 10; x++)
            if (x % 2)
                printf("%d is odd\n", x);
        return 0;
    }
    
    /* and.c */
    #include 
    
    int main(void)
    {
        int x;
        for (x = 0; x < 10; x++)
            if (x & 1)
                printf("%d is odd\n", x);
        return 0;
    }
    

    Затем я скомпилировал их с помощью gcc 4. 1. 3 на одной из моих машин 5 раз:

    • Без флагов оптимизации.
    • С -О
    • С -Ос
    • С -O2
    • С -O3

    Я проверил вывод сборки каждого компилятора (используя gcc -S) и обнаружил, что в каждом случае вывод для и. с и по модулю. c были идентичны (они оба использовали инструкцию andl $ 1,% eax). Я сомневаюсь, что это «новая» функция, и я подозреваю, что она восходит к древним версиям. Я также сомневаюсь, что какой-либо современный (созданный за последние 20 лет) неуместный компилятор, коммерческий или с открытым исходным кодом, не имеет такой оптимизации. Я бы протестировал другие компиляторы, но в данный момент у меня нет доступных.

    Если кто-то еще захочет протестировать другие компиляторы и / или целевые платформы и получит другой результат, мне было бы очень интересно узнать.

    Наконец, версия по модулю гарантируется стандартом для работы, является ли целое число положительным, отрицательным или нулевым, независимо от представления реализации целых чисел со знаком. Побитовая версия - нет. Да, я понимаю, что два дополнения несколько повсеместно, так что это не проблема.

    ответ дан Chris, с репутацией 12986, 2.10.2008
  • 209 рейтинг

    Вы, ребята, слишком эффективны. То, что вы действительно хотите, это:

    public boolean isOdd(int num) {
      int i = 0;
      boolean odd = false;
    
      while (i != num) {
        odd = !odd;
        i = i + 1;
      }
    
      return odd;
    }
    

    Повторите для isEven.

    Конечно, это не работает для отрицательных чисел. Но с блеском приходит жертва. , ,

    ответ дан SCdF, с репутацией 25108, 2.10.2008
  • 97 рейтинг

    Использовать битовую арифметику:

    if((x & 1) == 0)
        printf("EVEN!\n");
    else
        printf("ODD!\n");
    

    Это быстрее, чем при использовании деления или модуля.

    ответ дан Adam Pierce, с репутацией 21665, 2.10.2008
  • 36 рейтинг

    [Joke mode = "on"]

    public enum Evenness
    {
      Unknown = 0,
      Even = 1,
      Odd = 2
    }
    
    public static Evenness AnalyzeEvenness(object o)
    {
    
      if (o == null)
        return Evenness.Unknown;
    
      string foo = o.ToString();
    
      if (String.IsNullOrEmpty(foo))
        return Evenness.Unknown;
    
      char bar = foo[foo.Length - 1];
    
      switch (bar)
      {
         case '0':
         case '2':
         case '4':
         case '6':
         case '8':
           return Evenness.Even;
         case '1':
         case '3':
         case '5':
         case '7':
         case '9':
           return Evenness.Odd;
         default:
           return Evenness.Unknown;
      }
    }
    

    [Joke mode = "off"]

    РЕДАКТИРОВАТЬ: Добавлены путающие значения в перечисление.

    ответ дан Sklivvz, с репутацией 23395, 2.10.2008
  • 16 рейтинг

    В ответ на ffpf - у меня был точно такой же аргумент с коллегой много лет назад, и ответ - , а не , он не работает с отрицательными числами.

    Стандарт C предусматривает, что отрицательные числа могут быть представлены тремя способами:

    • 2-е дополнение
    • 1 дополнение
    • знак и величина

    Проверка как это:

    isEven = (x & 1);
    

    будет работать для дополнения 2 и представления знака и величины, но не для дополнения 1.

    Тем не менее, я считаю, что следующее будет работать для всех случаев:

    isEven = (x & 1) ^ ((-1 & 1) | ((x < 0) ? 0 : 1)));
    

    Спасибо ffpf за то, что он указал, что текстовое поле съедает все после моего менее чем персонажа!

    ответ дан Andrew Edgecombe, с репутацией 28627, 2.10.2008
  • 14 рейтинг

    Хороший это:

    /*forward declaration, C compiles in one pass*/
    bool isOdd(unsigned int n);
    
    bool isEven(unsigned int n)
    {
      if (n == 0) 
        return true ;  // I know 0 is even
      else
        return isOdd(n-1) ; // n is even if n-1 is odd
    }
    
    bool isOdd(unsigned int n)
    {
      if (n == 0)
        return false ;
      else
        return isEven(n-1) ; // n is odd if n-1 is even
    }
    

    Обратите внимание, что этот метод использует хвостовую рекурсию, включающую две функции. Это может быть эффективно реализовано (превращено в цикл время / пока), если ваш компилятор поддерживает хвостовую рекурсию, как компилятор Scheme. В этом случае стек не должен переполняться!

    ответ дан Pierre, с репутацией 2520, 2.10.2008
  • 11 рейтинг

    Число является четным, если при делении на два остаток равен 0. Число является нечетным, если при делении на 2 остаток равен 1.

    // Java
    public static boolean isOdd(int num){
        return num % 2 != 0;
    }
    
    /* C */
    int isOdd(int num){
        return num % 2;
    }
    

    Методы отличные!

    ответ дан jjnguy, с репутацией 104605, 2.10.2008
  • 8 рейтинг
    i % 2 == 0
    
    ответ дан Mark Cidade, с репутацией 82855, 2.10.2008
  • 7 рейтинг

    Я бы сказал, просто разделите его на 2, и если есть остаток 0, он четный, иначе он нечетный.

    Использование модуля (%) делает это легко.

    например 4% 2 = 0, поэтому 4 чётно 5% 2 = 1, поэтому 5 нечетное

    ответ дан Jarod Elliott, с репутацией 12451, 2.10.2008
  • 6 рейтинг

    Я бы построил таблицу четностей (0, если даже 1, если нечетное) целых чисел (так что можно было бы сделать поиск: D), но gcc не позволил бы мне создавать массивы таких размеров:

    typedef unsigned int uint;
    
    char parity_uint [UINT_MAX];
    char parity_sint_shifted [((uint) INT_MAX) + ((uint) abs (INT_MIN))];
    char* parity_sint = parity_sint_shifted - INT_MIN;
    
    void build_parity_tables () {
        char parity = 0;
        unsigned int ui;
        for (ui = 1; ui <= UINT_MAX; ++ui) {
            parity_uint [ui - 1] = parity;
            parity = !parity;
        }
        parity = 0;
        int si;
        for (si = 1; si <= INT_MAX; ++si) {
            parity_sint [si - 1] = parity;
            parity = !parity;
        }
        parity = 1;
        for (si = -1; si >= INT_MIN; --si) {
            parity_sint [si] = parity;
            parity = !parity;
        }
    }
    
    char uparity (unsigned int n) {
        if (n == 0) {
            return 0;
        }
        return parity_uint [n - 1];
    }
    
    char sparity (int n) {
        if (n == 0) {
            return 0;
        }
        if (n < 0) {
            ++n;
        }
        return parity_sint [n - 1];
    }
    

    Итак, давайте вместо этого прибегнем к математическому определению четных и нечетных.

    Целое число n четное, если существует такое целое число k, что n = 2k.

    Целое число n нечетно, если существует такое целое число k, что n = 2k + 1.

    Вот код для этого:

    char even (int n) {
        int k;
        for (k = INT_MIN; k <= INT_MAX; ++k) {
            if (n == 2 * k) {
                return 1;
            }
        }
        return 0;
    }
    
    char odd (int n) {
        int k;
        for (k = INT_MIN; k <= INT_MAX; ++k) {
            if (n == 2 * k + 1) {
                return 1;
            }
        }
        return 0;
    }
    

    Пусть C-целые числа обозначают возможные значения int в данной C-компиляции. (Обратите внимание, что C-целые числа являются подмножеством целых чисел. )

    Теперь можно беспокоиться о том, что для данного n в C-целых числах соответствующее целое число k может не существовать в C-целых числах. Но с небольшим доказательством можно показать, что для всех целых чисел n, | n | & lt; = | 2n | (*), где | n | равно "n, если n положительно, и -n в противном случае". Другими словами, для всех n в целых числах выполняется, по крайней мере, одно из следующих (на самом деле точно либо случаев (1 и 2), либо случаев (3 и 4), но я не буду здесь это доказывать):

    Случай 1: n & lt; = 2n.

    Случай 2: -n & lt; = -2n.

    Случай 3: -n & lt; = 2n.

    Случай 4: n & lt; = -2n.

    Теперь возьмите 2k = n. (Такое k существует, если n четное, но я не буду здесь это доказывать. Если n не является даже тогда, то цикл в even не может вернуться рано так или иначе, так что это не имеет значения. ) Но это подразумевает k & lt; n, если n не 0 с помощью (*) и тот факт (опять-таки не доказанный здесь), что для всех m, z в целых числах 2m = z означает, что z не равно m, учитывая, что m не равно 0. В случае, когда n равно 0, 2 * 0 = 0, поэтому 0 является четным, что мы закончили (если n = 0, то 0 находится в C-целых числах, потому что n находится в C-целом числе в функции even, следовательно, k = 0 находится в C -целый). Таким образом, такое k в C-целых числах существует для n в C-целых числах, если n четное.

    Аналогичный аргумент показывает, что если n нечетно, существует такое k в C-целых числах, что n = 2k + 1.

    Следовательно, представленные здесь функции even и odd будут работать правильно для всех C-целых чисел.

    ответ дан Thomas Eding, с репутацией 22142, 26.02.2010
  • 6 рейтинг

    Еще одно решение проблемы
    (дети могут голосовать)

    bool isEven(unsigned int x)
    {
      unsigned int half1 = 0, half2 = 0;
      while (x)
      {
         if (x) { half1++; x--; }
         if (x) { half2++; x--; }
    
      }
      return half1 == half2;
    }
    
    ответ дан eugensk00, с репутацией 1522, 2.10.2008
  • 5 рейтинг

    Как сообщают некоторые люди, существует множество способов сделать это. Согласно этот сайт , самый быстрый способ это оператор модуля:

    if (x % 2 == 0)
                   total += 1; //even number
            else
                   total -= 1; //odd number
    

    Однако, вот еще некоторый другой код, который был отмечен автором как , который работал медленнее, чем обычная операция по модулю выше:

    if ((x & 1) == 0)
                   total += 1; //even number
            else
                   total -= 1; //odd number
    
    System.Math.DivRem((long)x, (long)2, out outvalue);
            if ( outvalue == 0)
                   total += 1; //even number
            else
                   total -= 1; //odd number
    
    if (((x / 2) * 2) == x)
                   total += 1; //even number
            else
                   total -= 1; //odd number
    
    if (((x >> 1) << 1) == x)
                   total += 1; //even number
            else
                   total -= 1; //odd number
    
            while (index > 1)
                   index -= 2;
            if (index == 0)
                   total += 1; //even number
            else
                   total -= 1; //odd number
    
    tempstr = x.ToString();
            index = tempstr.Length - 1;
            //this assumes base 10
            if (tempstr[index] == '0' || tempstr[index] == '2' || tempstr[index] == '4' || tempstr[index] == '6' || tempstr[index] == '8')
                   total += 1; //even number
            else
                   total -= 1; //odd number
    

    Сколько людей даже знали о математике ? Система. DivRem метод или почему они будут использовать его? ?

    ответ дан Do What You Love, с репутацией 645, 9.07.2014
  • 5 рейтинг
    // C#
    bool isEven = ((i % 2) == 0);
    
    ответ дан Michael Petrotta, с репутацией 50538, 2.10.2008
  • 4 рейтинг

    Это продолжение обсуждения с @RocketRoy относительно его ответа , но оно может быть полезно всем, кто хочет сравнить эти результаты.

    tl; dr Из того, что я видел, подход Роя ((0xFFFFFFFF == (x | 0xFFFFFFFE)) не полностью оптимизирован до x & 1, как подход mod, но на практике время выполнения должно быть одинаковым во всех случаях.

    Итак, сначала я сравнил скомпилированный вывод, используя Compiler Explorer :

    Проверенные функции:

    int isOdd_mod(unsigned x) {
        return (x % 2);
    }
    
    int isOdd_and(unsigned x) {
        return (x & 1);
    }
    
    int isOdd_or(unsigned x) {
        return (0xFFFFFFFF == (x | 0xFFFFFFFE));
    }   
    

    CLang 3. 9. 0 с -O3:

    isOdd_mod(unsigned int):                          # @isOdd_mod(unsigned int)
            and     edi, 1
            mov     eax, edi
            ret
    
    isOdd_and(unsigned int):                          # @isOdd_and(unsigned int)
            and     edi, 1
            mov     eax, edi
            ret
    
    isOdd_or(unsigned int):                           # @isOdd_or(unsigned int)
            and     edi, 1
            mov     eax, edi
            ret
    

    GCC 6. 2 с -O3:

    isOdd_mod(unsigned int):
            mov     eax, edi
            and     eax, 1
            ret
    
    isOdd_and(unsigned int):
            mov     eax, edi
            and     eax, 1
            ret
    
    isOdd_or(unsigned int):
            or      edi, -2
            xor     eax, eax
            cmp     edi, -1
            sete    al
            ret
    

    Сняв шапку с CLang, он понял, что все три случая функционально равны. Тем не менее, подход Роя не оптимизирован в GCC, поэтому YMMV.

    Это похоже на Visual Studio; осматривая разборку Выпуск x64 (VS2015) для этих трех функций, я мог видеть, что часть сравнения одинакова для случаев "мод" и "и", и немного больше для случая Роя "или":

    // x % 2
    test bl,1  
    je (some address) 
    
    // x & 1
    test bl,1  
    je (some address) 
    
    // Roy's bitwise or
    mov eax,ebx  
    or eax,0FFFFFFFEh  
    cmp eax,0FFFFFFFFh  
    jne (some address)
    

    Однако после запуска фактического теста для сравнения этих трех параметров (обычный мод, поразрядный или, поразрядный и) результаты были полностью равны (опять же, Visual Studio 2005 x86 / x64, сборка выпуска, без отладчика).

    Выпуск сборки использует инструкцию test для случаев and и mod, в то время как случай Роя использует подход cmp eax,0FFFFFFFFh, но он в значительной степени развернут и оптимизирован, поэтому на практике нет никакой разницы.

    Мои результаты после 20 запусков (i7 3610QM, план электропитания Windows 10 установлен на High Performance):

    [Test: Plain mod 2 ] AVERAGE TIME: 689.29 ms (Relative diff.: +0.000%)
    [Test: Bitwise or  ] AVERAGE TIME: 689.63 ms (Relative diff.: +0.048%)
    [Test: Bitwise and ] AVERAGE TIME: 687.80 ms (Relative diff.: -0.217%)
    

    Разница между этими параметрами меньше 0. 3%, так что довольно очевидно, что сборка одинакова во всех случаях.

    Вот код, если кто-то захочет попробовать, с предупреждением, что я проверил его только в Windows (проверьте условие #if LINUX для определения get_time и реализуйте его при необходимости, взято из этого ответа ).

    #include 
    
    #if LINUX
    #include 
    #include 
    double get_time()
    {
        struct timeval t;
        struct timezone tzp;
        gettimeofday(&t, &tzp);
        return t.tv_sec + t.tv_usec*1e-6;
    }
    #else
    #include 
    double get_time()
    {
        LARGE_INTEGER t, f;
        QueryPerformanceCounter(&t);
        QueryPerformanceFrequency(&f);
        return (double)t.QuadPart / (double)f.QuadPart * 1000.0;
    }
    #endif
    
    #define NUM_ITERATIONS (1000 * 1000 * 1000)
    
    // using a macro to avoid function call overhead
    #define Benchmark(accumulator, name, operation) { \
        double startTime = get_time(); \
        double dummySum = 0.0, elapsed; \
        int x; \
        for (x = 0; x < NUM_ITERATIONS; x++) { \
            if (operation) dummySum += x; \
        } \
        elapsed = get_time() - startTime; \
        accumulator += elapsed; \
        if (dummySum > 2000) \
            printf("[Test: %-12s] %0.2f ms\r\n", name, elapsed); \
    }
    
    void DumpAverage(char *test, double totalTime, double reference)
    {
        printf("[Test: %-12s] AVERAGE TIME: %0.2f ms (Relative diff.: %+6.3f%%)\r\n",
            test, totalTime, (totalTime - reference) / reference * 100.0);
    }
    
    int main(void)
    {
        int repeats = 20;
        double runningTimes[3] = { 0 };
        int k;
    
        for (k = 0; k < repeats; k++) {
            printf("Run %d of %d...\r\n", k + 1, repeats);
            Benchmark(runningTimes[0], "Plain mod 2", (x % 2));
            Benchmark(runningTimes[1], "Bitwise or", (0xFFFFFFFF == (x | 0xFFFFFFFE)));
            Benchmark(runningTimes[2], "Bitwise and", (x & 1));
        }
    
        {
            double reference = runningTimes[0] / repeats;
            printf("\r\n");
            DumpAverage("Plain mod 2", runningTimes[0] / repeats, reference);
            DumpAverage("Bitwise or", runningTimes[1] / repeats, reference);
            DumpAverage("Bitwise and", runningTimes[2] / repeats, reference);
        }
    
        getchar();
    
        return 0;
    }
    
    ответ дан Lou, с репутацией 1405, 14.10.2016
  • 4 рейтинг

    Читая это довольно занимательное обсуждение, я вспомнил, что у меня была реальная, чувствительная ко времени функция, которая проверяла нечетные и четные числа внутри основного цикла. Это целочисленная функция мощности, размещенная в другом месте в StackOverflow следующим образом. Тесты были довольно удивительными. По крайней мере, в этой реальной функции по модулю медленнее , и это значительно. Победителем, с большим отрывом, требующим 67% времени по модулю, является или (|) подход , и его нигде больше нет на этой странице.

    static dbl  IntPow(dbl st0, int x)  {
        UINT OrMask = UINT_MAX -1;
        dbl  st1=1.0;
        if(0==x) return (dbl)1.0;
    
        while(1 != x)   {
            if (UINT_MAX == (x|OrMask)) {     //  if LSB is 1...    
            //if(x & 1) {
            //if(x % 2) {
                st1 *= st0;
            }    
            x = x >> 1;  // shift x right 1 bit...  
            st0 *= st0;
        }
        return st1 * st0;
    }
    

    Для 300 миллионов циклов контрольные сроки следующие.

    3. 962 | и маска подходят

    4. 851 & amp; подход

    5. 850% приближения

    Для людей, которые думают, что теория или листинг на ассемблере приводят подобные аргументы, это должно быть предостерегающим рассказом. Горацио, на небесах и на земле больше вещей, о которых ты и не мечтал в своей философии.

    ответ дан Thomas Eding, с репутацией 22142, 4.05.2013
  • 4 рейтинг

    Попробуйте это: return (((a>>1)<<1) == a)

    Пример:

    a     =  10101011
    -----------------
    a>>1 --> 01010101
    a<<1 --> 10101010
    
    b     =  10011100
    -----------------
    b>>1 --> 01001110
    b<<1 --> 10011100
    
    ответ дан Kiril Aleksandrov, с репутацией 2249, 14.02.2014
  • 4 рейтинг

    Вот ответ в Ява:

    public static boolean isEven (Integer Number) {
        Pattern number = Pattern.compile("^.*?(?:[02]|8|(?:6|4))$");
        String num = Number.toString(Number);
        Boolean numbr = new Boolean(number.matcher(num).matches());
        return numbr.booleanValue();
    }
    
    ответ дан Thomas Eding, с репутацией 22142, 27.04.2012
  • 3 рейтинг

    В «творческой, но запутанной категории» я предлагаю:

    int isOdd(int n) { return n ^ n * n ? isOdd(n * n) : n; }
    

    Вариант на эту тему, специфичный для Microsoft C ++:

    __declspec(naked) bool __fastcall isOdd(const int x)
    {
        __asm
        {
            mov eax,ecx
            mul eax
            mul eax
            mul eax
            mul eax
            mul eax
            mul eax
            ret
        }
    }
    
    ответ дан DocMax, с репутацией 9749, 3.10.2008
  • 3 рейтинг

    Я знаю, что это просто синтаксический сахар, а применим только в. нет , но как насчет метода расширения. , ,

    public static class RudiGroblerExtensions
    {
        public static bool IsOdd(this int i)
        {
            return ((i % 2) != 0);
        }
    }
    

    Теперь вы можете сделать следующее

    int i = 5;
    if (i.IsOdd())
    {
        // Do something...
    }
    
    ответ дан rudigrobler, с репутацией 11740, 2.10.2008
  • 2 рейтинг

    Побитовый метод зависит от внутреннего представления целого числа. Modulo будет работать везде, где есть оператор по модулю. Например, некоторые системы фактически используют биты низкого уровня для тегирования (например, динамические языки), поэтому необработанные x & amp; Я не буду работать в этом случае.

    ответ дан Will Hartung, с репутацией 91374, 2.10.2008
  • 2 рейтинг

    IsOdd (int x) {return true; }

    Доказательство правильности - рассмотрим множество всех натуральных чисел и предположим, что существует непустой набор целых чисел, которые не являются нечетными. Поскольку целые положительные числа упорядочены, будет наименьшее нечетное число, что само по себе довольно странно, поэтому ясно, что число не может быть в наборе. Поэтому этот набор не может быть не пустым. Повторите эти действия для отрицательных целых чисел, за исключением того, что ищите наибольшее нечетное число.

    ответ дан plinth, с репутацией 39983, 2.10.2008
  • 2 рейтинг

    Портативный:

    i % 2 ? odd : even;
    

    Не переносимый:

    i & 1 ? odd : even;
    
    i << (BITS_PER_INT - 1) ? odd : even;
    
    ответ дан ilitirit, с репутацией 8107, 2.10.2008
  • 1 рейтинг

    Число Нулевой паритет | ноль http: // tinyurl. com / oexhr3k

    Последовательность кода Python.

    # defining function for number parity check
    def parity(number):
        """Parity check function"""
        # if number is 0 (zero) return 'Zero neither ODD nor EVEN',
        # otherwise number&1, checking last bit, if 0, then EVEN, 
        # if 1, then ODD.
        return (number == 0 and 'Zero neither ODD nor EVEN') \
                or (number&1 and 'ODD' or 'EVEN')
    
    # cycle trough numbers from 0 to 13 
    for number in range(0, 14):
        print "{0:>4} : {0:08b} : {1:}".format(number, parity(number))
    

    Выход:

       0 : 00000000 : Zero neither ODD nor EVEN
       1 : 00000001 : ODD
       2 : 00000010 : EVEN
       3 : 00000011 : ODD
       4 : 00000100 : EVEN
       5 : 00000101 : ODD
       6 : 00000110 : EVEN
       7 : 00000111 : ODD
       8 : 00001000 : EVEN
       9 : 00001001 : ODD
      10 : 00001010 : EVEN
      11 : 00001011 : ODD
      12 : 00001100 : EVEN
      13 : 00001101 : ODD
    
    ответ дан Pankaj Prakash, с репутацией 759, 21.09.2015
  • 1 рейтинг
    int isOdd(int i){
      return(i % 2);
    }
    

    сделано.

    ответ дан None, с репутацией 1670, 13.10.2008
  • 1 рейтинг

    Чтобы дать более подробную информацию о методе побитового оператора для тех из нас, кто не делал много булевой алгебры во время наших исследований, вот объяснение. Вероятно, не очень полезен для ОП, но мне хотелось прояснить, почему NUMBER & amp; 1 работает.

    Обратите внимание, что, как кто-то ответил выше, способ представления отрицательных чисел может остановить этот метод. Фактически он может даже нарушить метод оператора по модулю, поскольку каждый язык может отличаться в том, как он работает с отрицательными операндами.

    Однако, если вы знаете, что NUMBER всегда будет положительным, это работает хорошо.

    Как Туни выше указывал, что важна только последняя цифра в двоичном (и динарном).

    Логический логический элемент И требует, чтобы оба входа были 1 (или высоким напряжением) для 1, который должен быть возвращен.

    1 & amp; 0 = 0

    0 & amp; 1 = 0

    0 & amp; 0 = 0

    1 & amp; 1 = 1

    Если вы представляете какое-либо число как двоичное (здесь я использовал 8-битное представление), нечетные числа имеют 1 в конце, четные числа имеют 0.

    Например:

    1 = 00000001

    2 = 00000010

    3 = 00000011

    4 = 00000100

    Если вы возьмете любое число и используете побитовое AND (& amp; в java), то оно на 1 вернет 00000001, = 1, что означает, что число нечетное. Или 00000000 = 0, то есть число четное.

    E. г

    Странно?

    1 & amp; 1 =

    00000001 & amp;

    00000001 =

    00000001 & lt; - нечетное

    2 & amp; 1 =

    00000010 & amp;

    00000001 =

    00000000 & lt; Четный

    54 & amp; 1 =

    00000001 & amp;

    00110110 =

    00000000 & lt; Четный

    Вот почему это работает:

    if(number & 1){
    
       //Number is odd
    
    } else {
    
       //Number is even
    }
    

    Извините, если это избыточно.

    ответ дан Astridax, с репутацией 134, 11.09.2013
  • 1 рейтинг
    I execute this code for ODD & EVEN:
    
    #include 
    int main()
    {
        int number;
        printf("Enter an integer: ");
        scanf("%d", &number);
    
        if(number % 2 == 0)
            printf("%d is even.", number);
        else
            printf("%d is odd.", number);
    }
    
    ответ дан Omar Faruk, с репутацией 219, 1.08.2017
  • 0 рейтинг

    Проверка четного или нечетного является простой задачей.

    Мы знаем, что любое число, в точности делимое на 2, является четным числом, а нечетным.

    Нам просто нужно проверить делимость любого числа и для проверки делимости мы используем % оператор

    Проверка четного нечетного с помощью if else

    if(num%2 ==0)  
    {
        printf("Even");
    }
    else
    {
        printf("Odd");
    }
    

    C программа для проверки четного или нечетного использования, если еще

    Использование условного / троичного оператора

    (num%2 ==0) printf("Even") : printf("Odd");
    

    Программа C для проверки четности или нечетности с использованием условного оператора .

    Использование побитового оператора

    if(num & 1)  
    {
        printf("Odd");
    }
    else 
    {
        printf("Even");
    }
    
    ответ дан Pankaj Prakash, с репутацией 759, 8.06.2015
  • 0 рейтинг

    + 66% быстрее & gt; !(i%2) / i%2 == 0

    int isOdd(int n)
    {
        return n & 1;
    }
    

    Код проверяет последний бит целого числа, если он 1 в двоичном коде

    Объяснение

    Binary  :   Decimal
    -------------------
    0000    =   0
    0001    =   1
    0010    =   2
    0011    =   3
    0100    =   4
    0101    =   5
    0110    =   6
    0111    =   7
    1000    =   8
    1001    =   9
    and so on...
    

    Обратите внимание, , самый правый бит всегда равен 1 для Нечетных номеров.

    , & amp; побитовое И оператор проверяет самый правый бит в нашей строке , возвращающей , если это 1

    Думайте об этом как об истинном. ложь

    Когда мы сравниваем n с 1 , что означает 0001 в двоичном формате (количество нулей не имеет значения).
    тогда давайте просто представим, что у нас есть целое число n размером 1 байт.

    Он будет представлен 8-битными / 8-битными цифрами.

    Если int n был 7 , и мы сравниваем его с 1 , это похоже на

    7 (1-byte int)|    0  0  0  0    0  1  1  1
           &
    1 (1-byte int)|    0  0  0  0    0  0  0  1
    ********************************************
    Result        |    F  F  F  F    F  F  F  T
    

    Который F обозначает false, а T - true.

    Это сравнивает только самый правый бит, если они оба верны. Так, автоматически 7 & 1 составляет т ру.

    Что, если я хочу проверить бит до самого правого?

    Просто измените n & 1 на n & 2, что означает 2 0010 в двоичном и т. Д.

    Я предлагаю использовать шестнадцатеричное обозначение, если вы новичок в побитовых операциях
    return n & 1; & gt; & gt; return n & 0x01;.

    ответ дан X Stylish, с репутацией 1291, 28.04.2018
  • 0 рейтинг

    Ради обсуждения. , ,

    Вам нужно только взглянуть на последнюю цифру любого заданного числа, чтобы увидеть, является ли она четной или нечетной. Подписанный, неподписанный, положительный, отрицательный - все они одинаковы в этом отношении. Так что это должно работать со всех сторон: -

    void tellMeIfItIsAnOddNumberPlease(int iToTest){
      int iLastDigit;
      iLastDigit = iToTest - (iToTest / 10 * 10);
      if (iLastDigit % 2 == 0){
        printf("The number %d is even!\n", iToTest);
      } else {
        printf("The number %d is odd!\n", iToTest);
      }
    }
    

    Ключ здесь находится в третьей строке кода, оператор деления выполняет целочисленное деление, поэтому в результате пропускается дробная часть результата. Так, например, 222/10 даст 22 в результате. Затем умножьте это снова на 10 и получите 220. Вычтите это из исходного 222, и вы получите 2, что по волшебству совпадает с последней цифрой в оригинальном номере. ;-) Круглые скобки напоминают нам о порядке выполнения расчетов. Сначала выполните деление и умножение, затем вычтите результат из исходного числа. Мы могли бы их опустить, поскольку приоритет для деления и умножения выше, чем для вычитания, но это дает нам «более читаемый» код.

    Мы могли бы сделать все это совершенно нечитаемым, если бы захотели. Для современного компилятора не было бы никакой разницы: -

    printf("%d%s\n",iToTest,0==(iToTest-iToTest/10*10)%2?" is even":" is odd");
    

    Но это усложнит поддержку кода в будущем. Просто представьте, что вы хотели бы изменить текст для нечетных чисел на "не четный". Затем кто-то еще позже захочет узнать, какие изменения вы сделали, и выполнить svn diff или подобное. , ,

    Если вы не беспокоитесь о переносимости, а больше о скорости, вы можете взглянуть на наименее значимый бит. Если этот бит установлен в 1, это нечетное число, если это 0, это четное число. В системе с прямым порядком байтов, такой как архитектура Intel x86, это будет примерно так: -

    if (iToTest & 1) {
      // Even
    } else {
      // Odd
    }
    
    ответ дан Tooony, с репутацией 2295, 2.10.2008
  • 0 рейтинг

    Если вы хотите быть эффективными, используйте побитовые операторы (x & 1), но если вы хотите быть читаемыми, используйте модуль 2 (x % 2)

    ответ дан Vihung, с репутацией 5626, 3.10.2008
  • -1 рейтинг

    Оператор модуля '%' можно использовать для проверки, является ли число нечетным или четным. То есть, когда число делится на 2, а если остаток равен 0, то это четное число, а нечетное число.

    #include 
    int main()
    {
        int n;//using modulus operator
        scanf("%d",&n);//take input n from STDIN 
        printf("%s",n%2==0?"Even":"Odd");//prints Even/Odd depending on n to STDOUT
        return 0;
    }
    

    Но использование битовых манипуляций происходит намного быстрее, чем в приведенном выше методе, поэтому, если вы возьмете число и примените логически И '& amp;' для него, если ответ 1, то его четное еще нечетное. То есть в основном мы должны проверить последний бит числа n в двоичном виде. Если последний бит равен 0, то n является четным, иначе его нечетным.

    например: предположим, N = 15, в двоичном N = 1111, теперь мы И это с 1

        1111
        0001
       &-----
        0001
    

    Поскольку результат равен 1, число N = 15 является нечетным.

    Снова, предположим, N = 8, в двоичном N = 1000, теперь мы И это с 1

        1000
        0001
       &-----
        0000
    

    Поскольку результат равен 0, число N = 8 является четным.

    #include 
    
    int main()
    {
        int n;//using AND operator
        scanf("%d",&n);//take input n from STDIN 
        printf("%s",n&1?"Odd":"Even");//prints Even/Odd depending on n to STDOUT
        return 0;
    }
    
    ответ дан Moinak Debnath, с репутацией 6, 16.05.2016