Como posso verificar se um número inteiro é par ou ímpar? [fechadas]

StackOverflow https://stackoverflow.com/questions/160930

  •  03-07-2019
  •  | 
  •  

Pergunta

Como posso verificar se um determinado número é par ou ímpar em C?

Foi útil?

Solução

Use o módulo (%) do operador para verificar se há um restante quando dividindo por 2:

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

Algumas pessoas criticaram a minha resposta acima afirmando que o uso de x e 1 é "mais rápido" ou "mais eficiente". Eu não acredito que este seja o caso.

Por curiosidade, eu criei dois programas caso de teste trivial:

/* modulo.c */
#include <stdio.h>

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 <stdio.h>

int main(void)
{
    int x;
    for (x = 0; x < 10; x++)
        if (x & 1)
            printf("%d is odd\n", x);
    return 0;
}

Em seguida, compilado los com gcc 4.1.3 em uma de minhas máquinas 5 vezes diferentes:

  • Sem opções de otimização.
  • Com -O
  • Com -Os
  • Com -O2
  • Com O3

I examinou a saída de cada conjunto de compilação (usando gcc -S) e descobriram que, em cada caso, a saída para and.c e modulo.c eram idênticos (ambos utilizados a andl US $ 1,% eax instrução). Eu duvido que este é um recurso "novo", e eu suspeito que remonta a versões antigas. Eu também duvido que qualquer moderno (feito nos últimos 20 anos) compilador não arcano, comercial ou open source, carece de tal otimização. Gostaria de testar em outros compiladores, mas eu não tenho nenhum disponível no momento.

Se qualquer outra pessoa teria o cuidado de testar outros compiladores e / ou metas de plataforma, e obtém um resultado diferente, eu estaria muito interessado em saber.

Finalmente, a versão modulo é garantida pelo padrão de trabalho se o inteiro é positivo, negativo ou zero, independentemente da representação de inteiros assinados da implementação. O bit a bit-e versão não é. Sim, eu percebo complemento de dois é um pouco onipresente, então isso não é realmente um problema.

Outras dicas

Vocês são waaaaaaaay muito eficiente. O que você realmente quer é:

public boolean isOdd(int num) {
  int i = 0;
  boolean odd = false;

  while (i != num) {
    odd = !odd;
    i = i + 1;
  }

  return odd;
}

Repita para isEven.

É claro que isso não funciona para números negativos. Mas com brilho vem sacrifício ...

Use mordeu aritmética:

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

Esta é mais rápido do que usando divisão ou módulo.

[Modo Joke = "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;
  }
}

[Modo Joke = "off"]

EDIT:. Adicionado confundir valores para o enum

Em resposta a ffpf -. Eu tinha exatamente o mesmo argumento com um colega anos, ea resposta é não , ele não funciona com números negativos

Os estipula padrão C que números negativos podem ser representados de 3 formas:

  • 2 de complemento
  • 1 do complemento
  • sinal e magnitude

Verificar assim:

isEven = (x & 1);

irá trabalhar para complemento de 2 e representação sinal e magnitude, mas não para complemento de 1.

No entanto, acredito que a seguir irá funcionar para todos os casos:

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

Graças a ffpf por apontar que a caixa de texto estava comendo tudo depois da minha menos de personagem!

Um bom um é:

/*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
}

Note que este uso do método cauda recursão envolvendo duas funções. Pode ser implementado de forma eficiente (se transformou em um tempo / até que tipo de laço), se suas sustentações do compilador cauda recursão como um compilador Scheme. Neste caso, a pilha não deve ultrapassar!

Um número é mesmo que, quando dividido por dois, o restante é 0. Um número é estranho se, quando dividido por dois, o restante é 1.

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

/* C */
int isOdd(int num){
    return num % 2;
}

Os métodos são ótimos!

i % 2 == 0

Eu diria apenas dividi-lo por 2 e se houver um 0 restante, é ainda, caso contrário, é estranho.

Usando o módulo (%) torna isso fácil.

por exemplo. 4% 2 = 0 4, por conseguinte, é ainda 5% 2 = 1, portanto, 5 é impar

Mais uma solução para o problema
(as crianças são bem-vindos a voto)

bool isEven(unsigned int x)
{
  unsigned int half1 = 0, half2 = 0;
  while (x)
  {
     if (x) { half1++; x--; }
     if (x) { half2++; x--; }

  }
  return half1 == half2;
}

Gostaria de construir uma tabela das paridades (0 se ainda 1 se ímpar) dos inteiros (por isso pode-se fazer uma pesquisa: D), mas gcc não me deixa fazer matrizes de tais tamanhos:

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

Então, vamos em vez recorrer à definição matemática de pares e ímpares, em vez.

Um número inteiro n é mesmo se existe um número inteiro k tal que n = 2k.

Um número inteiro n é estranho se existe um número inteiro k tal que n = 2k + 1.

Aqui está o código para ele:

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

Let C-inteiros denotam os valores possíveis de int em uma determinada compilação C. (Note-se que C-inteiros é um subconjunto dos inteiros.)

Agora, uma preocupação poder que para um dado n em C-inteiros que o inteiro correspondente k não pode existir dentro de C-inteiros. Mas com um pouco de prova que é possível mostrar que para todos os inteiros n, | n | <= | 2n | (*), Onde | n | é "n se n for positivo e -n de outra forma". Em outras palavras, para todo n em números inteiros pelo menos um dos seguintes detém (exatamente qualquer dos casos (1 e 2) ou casos (3 e 4), de fato, mas não vou provar isso aqui):

Caso 1:. N <= 2n

Caso 2:. -N <= 2n

Caso 3:. -N <= 2n

Caso 4:. N <= 2n

Agora pegue 2k = n. (Tal ak existe se n for par, mas não vou provar isso aqui. Se n não é, mesmo assim, o loop em even não retornar no início de qualquer maneira, por isso não importa.) Mas isso implica k even função, por conseguinte, k = 0 está em C-inteiros). Assim, um tal k em C-inteiros existe para n em C-inteiros, se n for mesmo.

A mostra argumento similar que, se n é ímpar, existe um k em C-inteiros tais que n = 2k + 1.

Assim, as funções even e odd apresentado aqui vai funcionar corretamente para todos os C-inteiros.

// C#
bool isEven = ((i % 2) == 0);

Aqui está uma resposta em Java:

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

Tente isto: return (((a>>1)<<1) == a)

Exemplo:

a     =  10101011
-----------------
a>>1 --> 01010101
a<<1 --> 10101010

b     =  10011100
-----------------
b>>1 --> 01001110
b<<1 --> 10011100

A leitura deste discussão bastante divertido, eu lembrei que eu tinha uma função no mundo real, sensível ao tempo que testou para números pares e ímpares dentro do loop principal. É uma função de potência inteira, publicado em outro lugar no StackOverflow, como segue. Os benchmarks foram bastante surpreendentes. Pelo menos nesta função no mundo real, modulo é mais lento , e de forma significativa. O vencedor, por uma larga margem, exigindo 67% do tempo de modulo, é um ou | abordagem , e está longe de ser encontrada em outro lugar nesta página ().

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

Para 300 milhões de loops, os intervalos de referência são os seguintes.

3.962 a | e abordagem a máscara

4.851 a & abordagem

5.850 a abordagem%

Para pessoas que pensam teoria, ou listando uma linguagem de montagem, se instala argumentos como estes, este deve ser um conto preventivo. Existem mais coisas entre o céu ea terra, Horácio, do que sonha a sua filosofia.

Este é um acompanhamento para a discussão com @RocketRoy sobre sua resposta , mas pode ser útil para quem quer comparar estes resultados.

tl; dr Pelo que tenho visto, a abordagem de Roy ((0xFFFFFFFF == (x | 0xFFFFFFFE)) não é totalmente otimizado para x & 1 como a abordagem mod, mas na prática tempos de execução deve vir igual em todos os casos <. / p>

Então, primeiro eu comparei a saída compilado usando Compiler Explorador :

Funções testado:

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 com 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 com 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

Chapéus até Clang, ele percebeu que todos os três casos são funcionalmente iguais. No entanto, a abordagem de Roy não é otimizado em GCC, assim YMMV.

É semelhante com o Visual Studio; inspecionando a desmontagem lançamento x64 (VS2015) para essas três funções, pude ver que a parte de comparação é igual para "mod" e "e" casos, e ligeiramente maior para o caso do Roy "ou":

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

No entanto, após a execução de uma referência real para comparar estas três opções (mod simples, bit a bit ou, bit a bit e), os resultados foram completamente iguais (novamente, Visual Studio 2005 x86 / x64, compilação de lançamento, nenhum depurador anexado).

Release usa montagem a instrução test para casos and e mod, enquanto o caso de Roy usa a abordagem cmp eax,0FFFFFFFFh, mas está fortemente desenrolado e otimizada de modo que não há diferença na prática.

Os meus resultados após 20 corridas (i7 3610QM, o Windows conjunto plano de 10 poder de Alto Desempenho):

[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%)

A diferença entre essas opções é inferior a 0,3%, por isso é bastante óbvio a montagem é igual em todos os casos.

Aqui está o código se alguém quiser tentar, com uma ressalva que eu só testei no Windows (verifique o condicional #if LINUX para a definição get_time e implementá-lo, se necessário, tomadas a partir esta resposta ).

#include <stdio.h>

#if LINUX
#include <sys/time.h>
#include <sys/resource.h>
double get_time()
{
    struct timeval t;
    struct timezone tzp;
    gettimeofday(&t, &tzp);
    return t.tv_sec + t.tv_usec*1e-6;
}
#else
#include <windows.h>
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;
}

Eu sei que isto é apenas açúcar sintático e aplicável apenas em .net , mas o que dizer de método de extensão ...

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

Agora você pode fazer o seguinte

int i = 5;
if (i.IsOdd())
{
    // Do something...
}

Na "categoria criativo, mas confuso" Ofereço:

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

Uma variante sobre este tema que é específico para 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
    }
}

O método bit a bit depende da representação interna do número inteiro. Modulo irá trabalhar em qualquer lugar há um operador módulo. Por exemplo, alguns sistemas realmente usar os bits de baixo nível para marcar (como linguagens dinâmicas), de modo que a matéria-x e 1 não vai realmente trabalhar nesse caso.

IsOdd (int x) {return true; }

prova de correção - considerar o conjunto de todos os inteiros positivos e suponha que há um conjunto não vazio de inteiros que não são estranho. Porque inteiros positivos são bem-ordenada, haverá um número menor não estranha, que em si é muito estranho, tão claramente este número não pode estar no set. Por conseguinte, este conjunto não pode ser não-vazia. Repita para inteiros negativos, exceto olhar para o maior número ímpar não.

Portátil:

i % 2 ? odd : even;

portável:

i & 1 ? odd : even;

i << (BITS_PER_INT - 1) ? odd : even;

Como algumas pessoas postaram, existem inúmeras maneiras de fazer isso. De acordo com a este website , a maneira mais rápida é o operador módulo:

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

No entanto, aqui estão algumas outro código que foi bancada marcada pelo autor, que correu mais lento do que a operação de módulo comum acima:

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

Como muitas pessoas sequer sabiam da Math.System.DivRem método ou por que eles usá-lo ??

int isOdd(int i){
  return(i % 2);
}

feito.

Para dar mais elaboração no método operador bit a bit para aqueles de nós que não fez muito álgebra booleana durante nossos estudos, aqui está uma explicação. Provavelmente não de muita utilidade para o OP, mas eu senti como tornando-se claro por que NÚMERO e 1 obras.

Por favor, note como como alguém respondida acima, os números maneira negativos são representados pode parar este método de trabalho. Na verdade, pode até mesmo quebrar o método operador módulo também desde cada língua podem diferir na forma como ele lida com operandos negativos.

No entanto, se você sabe que o número será sempre positivo, isso funciona bem.

Como Tooony acima fez o ponto que apenas o último dígito binário (e denary) é importante.

A lógica e a porta booleanas ditames que ambas as entradas tem que ser um 1 (ou alta tensão) para um para ser devolvido.

1 & 0 = 0.

0 & 1 = 0.

0 e 0 = 0.

1 & 1 = 1.

Se você representar qualquer número como binário (eu usei uma representação de 8 bits aqui), números ímpares têm 1 no final, até mesmo números têm 0.

Por exemplo:

1 = 00000001

2 = 00000010

3 = 00000011

4 = 00000100

Se você tomar qualquer número e uso AND bit a bit (& em java)-lo por 1 ele quer voltar 00000001, = 1 significa que o número for ímpar. Ou 00000000 = 0, ou seja, o número é ainda.

exemplo

É estranho?

1 & 1 =

00000001 &

00000001 =

00000001 <- Odd

2 & 1 =

00000010 &

00000001 =

00000000 <- Mesmo

54 & 1 =

00000001 &

00110110 =

00000000 <- Mesmo

É por isso que isso funciona:

if(number & 1){

   //Number is odd

} else {

   //Number is even
}

Desculpe se isso é redundante.

Número Zero paridade | de zero http://tinyurl.com/oexhr3k

seqüência de código 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))

Output:

   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
I execute this code for ODD & EVEN:

#include <stdio.h>
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);
}

Por uma questão de discussão ...

Você só precisa olhar para o último dígito em qualquer número dado para ver se ele é par ou ímpar. Assinado, não assinado, positivo, negativo - eles são todos o mesmo com relação a isso. Portanto, este deve funcionar durante todo: -

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

A chave aqui é na terceira linha de código, as executa operador de divisão uma divisão inteira, de modo que resultado estão faltando a parte fração do resultado. Assim, por exemplo 222/10 vai dar 22 como um resultado. Em seguida, multiplicá-lo novamente com 10 e você tem 220. Subtrair que a partir do original 222 e você acaba com 2, que por mágica é o mesmo número que o último dígito do número original. ;-) O parêntesis estão lá para nos lembrar da ordem o cálculo é feito em. Primeiro faça a divisão ea multiplicação, em seguida, subtrair o resultado do número original. Nós poderíamos deixá-los fora, uma vez que a prioridade é maior para a divisão e multiplicação do que de subtração, mas isso dá-nos o código "mais legível".

Nós poderíamos fazer tudo completamente ilegível, se quiséssemos. Não faria nenhuma diferença para um compilador moderno: -

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

Mas faria o caminho de código mais difícil de manter no futuro. Basta imaginar que você gostaria de mudar o texto para números ímpares para "não é mesmo". Então alguém, mais tarde, quiser saber quais as mudanças que você fez e executar um diff svn ou similar ...

Se você não está preocupado com a portabilidade, mas mais sobre a velocidade, você poderia ter um olhar para o bit menos significativo. Se esse bit é definido para 1 é um número ímpar, se for 0 é um número par. Em um pequeno sistema endian, como a arquitetura x86 da Intel que seria algo assim: -

if (iToTest & 1) {
  // Even
} else {
  // Odd
}

Se você quer ser eficiente, operadores de uso bit a bit (x & 1), mas se você quer ser o uso legível módulo 2 (x % 2)

Verificar par ou ímpar é uma tarefa simples.

Sabemos que qualquer número exatamente divisível por 2 é ainda número pessoa estranha.

Nós só precisa verificar a divisibilidade de qualquer número e para verificar a divisibilidade usamos operador %

Verificar mesmo estranho usando if else

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

C para verificar par ou ímpar de usar se outra

Usando o Condicional / operador ternário

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

C programa para verificar par ou ímpar usando condicional operador .

Usando o operador bit a bit

if(num & 1)  
{
    printf("Odd");
}
else 
{
    printf("Even");
}

66% mais rápido> !(i%2) / i%2 == 0

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

O código verifica o último bit do inteiro se é 1 no binário

Explicação

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...

Aviso mais à direita pouco é sempre 1 para Odd números.

& bit a bit E operador verifica o bit mais à direita no nosso retorno linha se é 1 |

Pense nisso como verdadeiro e false

Quando comparamos n com 1 que meios 0001 em binário (número de zeros não importa).
então vamos apenas Imagine que temos o inteiro n com um tamanho de 1 byte.

Ele estaria representado por 8 bits dígitos / 8-binários.

Se o int n 7 e compará-lo com 1 , é como

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

Qual F significa falso e T para a verdadeira.

compara apenas o bit mais à direita se eles são ambos true. Então, automagicamente 7 & 1 é T rue.

E se eu quiser verificar o pouco antes do mais à direita?

Simplesmente mudar n & 1 para n & 2 que 2 representa 0010 em binário e assim por diante.

Eu sugiro usar a notação hexadecimal, se você é um iniciante a bit a bit operações
return n & 1; >> return n & 0x01;.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top