Como posso verificar se um determinado número é par ou ímpar em C?
Como posso verificar se um determinado número é par ou ímpar em C?
Respostas:
Use o operador modulo (%) para verificar se há um restante ao dividir por 2:
if (x % 2) { /* x is odd */ }
Algumas pessoas criticaram minha resposta acima afirmando que usar x & 1 é "mais rápido" ou "mais eficiente". Não acredito que seja esse o caso.
Por curiosidade, criei dois programas triviais de casos de teste:
/* 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, compilei isso com o gcc 4.1.3 em uma de minhas máquinas 5 vezes diferentes:
Examinei a saída de montagem de cada compilação (usando gcc-S) e descobri que, em cada caso, a saída para and.c e modulo.c eram idênticas (ambos usavam a instrução andl $ 1,% eax). Duvido que esse seja um "novo" recurso, e suspeito que remonta a versões antigas. Também duvido que qualquer compilador não arcano moderno (comercializado nos últimos 20 anos), de código aberto ou comercial, não tenha essa otimização. Eu testaria em outros compiladores, mas não tenho nenhum disponível no momento.
Se alguém mais gostaria de testar outros compiladores e / ou destinos de plataforma e obtiver um resultado diferente, eu ficaria muito interessado em saber.
Finalmente, a versão do módulo é garantida pelo padrão para trabalhar se o número inteiro é positivo, negativo ou zero, independentemente da representação da implementação de números inteiros assinados. A versão bit a bit e não é. Sim, eu sei que o complemento de dois é onipresente, então isso não é realmente um problema.
Vocês são muito eficientes. 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, isso não funciona para números negativos. Mas com brilho vem o sacrifício ...
Use aritmética de bits:
if((x & 1) == 0)
printf("EVEN!\n");
else
printf("ODD!\n");
Isso é mais rápido do que usar divisão ou módulo.
[Modo piada = "ativado"]
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 brincadeira = "desativado"]
EDIT: Adicionado valores confusos para a enumeração.
Em resposta ao ffpf - eu tive exatamente o mesmo argumento com um colega anos atrás, e a resposta é não , ele não funciona com números negativos.
O padrão C estipula que números negativos podem ser representados de três maneiras:
Verificando assim:
isEven = (x & 1);
funcionará no complemento de 2 e na representação de sinal e magnitude, mas não no complemento de 1.
No entanto, acredito que o seguinte funcionará para todos os casos:
isEven = (x & 1) ^ ((-1 & 1) | ((x < 0) ? 0 : 1)));
Agradeço ao ffpf por apontar que a caixa de texto estava comendo tudo depois do meu personagem menor que o!
Uma boa é:
/*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
}
Observe que esse método usa recursão de cauda envolvendo duas funções. Ele pode ser implementado com eficiência (transformado em um tipo de loop de tempo / até) se o seu compilador suportar recursão de cauda como um compilador Scheme. Nesse caso, a pilha não deve transbordar!
Um número é par se, quando dividido por dois, o restante for 0. Um número será ímpar se, quando dividido por 2, o restante for 1.
// Java
public static boolean isOdd(int num){
return num % 2 != 0;
}
/* C */
int isOdd(int num){
return num % 2;
}
Métodos são ótimos!
i % 2 == 0
Eu diria que basta dividi-lo por 2 e se houver um 0 restante, é par; caso contrário, é estranho.
Usar o módulo (%) facilita isso.
por exemplo. 4% 2 = 0 portanto 4 é par 5% 2 = 1 portanto 5 é ímpar
Mais uma solução para o problema
(as crianças podem votar)
bool isEven(unsigned int x)
{
unsigned int half1 = 0, half2 = 0;
while (x)
{
if (x) { half1++; x--; }
if (x) { half2++; x--; }
}
return half1 == half2;
}
Eu criaria uma tabela de paridades (0 se 1 igual a ímpar) dos números inteiros (para que se pudesse fazer uma pesquisa: D), mas o gcc não me permite fazer matrizes de tamanhos iguais:
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 recorrer à definição matemática de par e ímpar.
Um número inteiro n é uniforme se existir um número inteiro k tal que n = 2k.
Um número inteiro n é ímpar se existir um número k tal que n = 2k + 1.
Aqui está o código para isso:
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 possíveis valores de int
em uma dada compilação C. (Observe que C-inteiros é um subconjunto dos inteiros.)
Agora, pode-se preocupar que, para um dado n em C-inteiros, o número inteiro correspondente k possa não existir em C-inteiros. Mas com uma pequena prova, pode-se mostrar que para todos os números inteiros n, | n | <= | 2n | (*), onde | n | é "n se n for positivo e -n caso contrário". Em outras palavras, para todos os n em números inteiros, pelo menos um dos itens a seguir é válido (exatamente os casos (1 e 2) ou os casos (3 e 4), de fato, mas não vou provar 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 eu não vou provar aqui. Se n for par, o loop in even
não retornará mais cedo, portanto não importa.) Mas isso implica k <n se n não 0 por (*) e o fato (novamente não provado aqui) de que para todo m, z em números inteiros 2m = z implica z diferente de m dado m não é 0. No caso n é 0, 2 * 0 = 0 então 0 é o mesmo que terminamos (se n = 0 então 0 está em números inteiros C porque n está em números inteiros C na funçãoeven
, portanto, k = 0 está em números inteiros C). Assim, tal ak em C-inteiros existe para n em C-inteiros se n for par.
Um argumento semelhante mostra que se n é ímpar, existe ak em números inteiros C de modo que n = 2k + 1.
Portanto, as funções even
e odd
apresentadas aqui funcionarão corretamente para todos os C-inteiros.
i % 2
é muito menor e provavelmente mais eficiente.
%2
funciona para todos os números inteiros.
// C#
bool isEven = ((i % 2) == 0);
typedef
ou #define
ou algo assim.
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 o seguinte: return (((a>>1)<<1) == a)
Exemplo:
a = 10101011
-----------------
a>>1 --> 01010101
a<<1 --> 10101010
b = 10011100
-----------------
b>>1 --> 01001110
b<<1 --> 10011100
Lendo essa discussão bastante divertida, lembrei que tinha uma função sensível ao tempo no mundo real que testava números ímpares e pares dentro do loop principal. É uma função de potência inteira, publicada em outro lugar no StackOverflow, da seguinte maneira. Os benchmarks foram bastante surpreendentes. Pelo menos nessa função do mundo real, o módulo é mais lento e significativamente mais. O vencedor, por uma ampla margem, exigindo 67% do tempo do módulo, é uma abordagem ou (|) , e não pode ser encontrado em nenhum 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 tempos de referência são os seguintes.
3.962 the | e abordagem de máscara
4.851 a abordagem
5.850 a abordagem%
Para pessoas que pensam que a teoria, ou uma listagem em linguagem assembly, resolve argumentos como esses, isso deve ser um conto de advertência. Há mais coisas no céu e na terra, Horácio, do que se sonha em sua filosofia.
unsigned x
como x = x >> 1;
é o comportamento definido pela implementação quando x < 0
. Não está claro por que x
e OrMask
diferem em tipo. Simples o suficiente para reescrever usando um while(x)
teste.
% 2
caso usando o bit a bit &
. Acabei de testar isso e os resultados são os mesmos (VS2015, a versão é compilada com todas as otimizações, x86 e x64). A resposta aceita também afirma isso para o GCC (escrito em 2008).
or
seria mais rápido que um and
é altamente improvável, em qualquer plataforma / compilador. Mesmo se houvesse uma combinação estranha de plataforma / compilador (e você não publicou nem isso nem o código usado para realizar a referência), dependendo de outros compiladores que se comportam da mesma forma, seria uma má aposta de otimização. Então, como eu escrevi, me pergunto em qual plataforma / compilador isso foi testado , porque tenho quase certeza de que não foi medido corretamente.
Este é um acompanhamento da discussão com o @RocketRoy sobre sua resposta , mas pode ser útil para quem quiser comparar esses resultados.
tl; dr Pelo que tenho visto, a abordagem de Roy ( (0xFFFFFFFF == (x | 0xFFFFFFFE)
) não está totalmente otimizado para x & 1
que a mod
abordagem, mas na prática tempos de execução deve vir iguais em todos os casos.
Então, primeiro comparei a saída compilada usando o Compiler Explorer :
Funções testadas:
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
Com o clang, percebemos que todos os três casos são funcionalmente iguais. No entanto, a abordagem de Roy não é otimizada no GCC, portanto, YMMV.
É semelhante ao Visual Studio; inspecionando a desmontagem do Release x64 (VS2015) para essas três funções, pude ver que a parte de comparação é igual para os casos "mod" e "e" e "e um pouco maior para o caso" ou "de Roy:
// 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 executar uma referência real para comparar essas três opções (modificação simples, bit a bit ou bit a bit e), os resultados foram completamente iguais (novamente, Visual Studio 2005 x86 / x64, versão Build, sem depurador anexado).
A montagem de liberação usa as test
instruções para and
emod
casos, enquanto o caso de Roy usa a cmp eax,0FFFFFFFFh
abordagem, mas é fortemente desenrolada e otimizada para que não haja diferença na prática.
Meus resultados após 20 execuções (i7 3610QM, plano de energia do Windows 10 definido como Alto desempenho):
[Teste: Modificação simples 2] TEMPO MÉDIO: 689,29 ms (Dif. Relativa: + 0,000%) [Teste: Bit a bit ou] TEMPO MÉDIO: 689,63 ms (Diferença relativa: + 0,048%) [Teste: Bit a bit e] TEMPO MÉDIO: 687,80 ms (Dif. Relativa: -0,217%)
A diferença entre essas opções é menor que 0,3%; portanto, é óbvio que a montagem é igual em todos os casos.
Aqui está o código, se alguém quiser tentar, com uma ressalva de que eu apenas o testei no Windows (verifique o #if LINUX
condicional para a get_time
definição e implemente-o, se necessário, retirado desta 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 isso é apenas açúcar sintático e aplicável apenas em .net, mas e o 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 criativa, mas confusa", ofereço:
int isOdd(int n) { return n ^ n * n ? isOdd(n * n) : n; }
Uma variante desse tema específica do 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. O módulo funcionará em qualquer lugar onde houver um operador de módulo. Por exemplo, alguns sistemas realmente usam os bits de baixo nível para marcação (como linguagens dinâmicas), para que o x & 1 bruto não funcione nesse caso.
IsOdd (int x) {return true; }
Prova de correção - considere o conjunto de todos os números inteiros positivos e suponha que exista um conjunto de números inteiros não vazios que não sejam ímpares. Como números inteiros positivos são bem ordenados, haverá um número menor e não ímpar, o que por si só é bastante ímpar, tão claramente que esse número não pode estar no conjunto. Portanto, este conjunto não pode estar vazio. Repita para números inteiros negativos, exceto procure o maior número não ímpar.
Como algumas pessoas postaram, existem várias maneiras de fazer isso. De acordo com este site , o caminho mais rápido é o operador de módulo:
if (x % 2 == 0)
total += 1; //even number
else
total -= 1; //odd number
No entanto, aqui está outro código que foi marcado pelo autor mais lento 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
Quantas pessoas conheciam o método Math.System.DivRem ou por que o usariam?
Para dar mais detalhes sobre o método do operador bit a bit para aqueles que não fizeram muita álgebra booleana durante nossos estudos, aqui está uma explicação. Provavelmente não é de muita utilidade para o OP, mas eu queria deixar claro por que o NUMBER & 1 funciona.
Observe que, como alguém respondeu acima, a maneira como os números negativos são representados pode interromper o funcionamento desse método. De fato, ele também pode quebrar o método do operador de módulo, pois cada idioma pode diferir na maneira como lida com operandos negativos.
No entanto, se você souber que NUMBER sempre será positivo, isso funcionará bem.
Como Tooony acima mencionou, apenas o último dígito em binário (e negação) é importante.
Uma lógica AND booleana dita que ambas as entradas devem ser 1 (ou alta tensão) para que 1 seja retornado.
1 e 0 = 0.
0 e 1 = 0.
0 e 0 = 0.
1 e 1 = 1.
Se você representa qualquer número como binário (usei uma representação de 8 bits aqui), os números ímpares têm 1 no final, os números pares têm 0.
Por exemplo:
1 = 00000001
2 = 00000010
3 = 00000011
4 = 00000100
Se você pegar qualquer número e usar AND bit a bit (& em java) por 1, retornará 00000001, = 1, o que significa que o número é ímpar. Ou 00000000 = 0, significando que o número é par.
Por exemplo
É estranho?
1 & 1 =
00000001 &
00000001 =
00000001 <- Ímpar
2 & 1 =
00000010 &
00000001 =
00000000 <- Par
54 & 1 =
00000001 &
00110110 =
00000000 <- Par
É por isso que isso funciona:
if(number & 1){
//Number is odd
} else {
//Number is even
}
Desculpe se isso é redundante.
Paridade de número zero | zero http://tinyurl.com/oexhr3k
Sequê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))
Resultado:
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 para ver se é par ou ímpar. Assinado, sem sinal, positivo, negativo - são todos iguais no que diz respeito a isso. Portanto, isso deve funcionar o tempo 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 está na terceira linha do código, o operador de divisão executa uma divisão inteira, para que o resultado esteja faltando a parte da fração do resultado. Por exemplo, 222/10 dará 22 como resultado. Em seguida, multiplique novamente por 10 e você terá 220. Subtraia isso do 222 original e você terminará com 2, que por mágica é o mesmo número que o último dígito no número original. ;-) Os parênteses estão aí para nos lembrar da ordem em que o cálculo é feito. Primeiro faça a divisão e a multiplicação, depois subtraia o resultado do número original. Poderíamos deixá-los de fora, pois a prioridade é mais alta para divisão e multiplicação do que para subtração, mas isso nos dá um código "mais legível".
Poderíamos tornar 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 isso tornaria o código muito mais difícil de manter no futuro. Imagine que você gostaria de alterar o texto dos números ímpares para "não é par". Então alguém mais tarde quer descobrir quais alterações você fez e executar um svn diff ou similar ...
Se você não está preocupado com a portabilidade, mas mais com a velocidade, pode dar uma olhada no bit menos significativo. Se esse bit estiver definido como 1, é um número ímpar; se for 0, é um número par. Em um pequeno sistema endian, como a arquitetura x86 da Intel, seria algo como isto: -
if (iToTest & 1) {
// Even
} else {
// Odd
}
Se você quer ser eficiente, use operadores bit a bit ( x & 1
), mas se quiser ser legível, use o módulo 2 ( x % 2
)
%
. Se você quiser que seja legível, use %
. Hmmm, eu vejo um padrão aqui.
Verificar par ou ímpar é uma tarefa simples.
Sabemos que qualquer número exatamente divisível por 2 é o número par mais ímpar.
Só precisamos verificar a divisibilidade de qualquer número e, para verificar a divisibilidade, usamos o %
operador
Verificando ímpares usando se mais
if(num%2 ==0)
{
printf("Even");
}
else
{
printf("Odd");
}
Programa C para verificar par ou ímpar usando se mais
Usando o operador Condicional / Ternário
(num%2 ==0) printf("Even") : printf("Odd");
Programa C para verificar par ou ímpar usando o operador condicional .
Usando o operador Bitwise
if(num & 1)
{
printf("Odd");
}
else
{
printf("Even");
}
!(i%2) / i%2 == 0
int isOdd(int n)
{
return n & 1;
}
O código verifica o último bit do número inteiro se é 1 em binário
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...
Observe que o bit mais à direita é sempre 1 para números ímpares .
os & bit a bit E operador verifica o bit mais à direita em nosso retorno linha Se for 1
Quando comparamos n com 1, o que significa 0001
em binário (o número de zeros não importa).
então vamos apenas imaginar que temos o número inteiro n com tamanho de 1 byte.
Seria representado por dígitos de 8 bits / 8 binários.
Se o int n era 7 e o comparamos 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 como verdadeiro.
Ele compara apenas o bit mais à direita se ambos forem verdadeiros. Então, automagicamente
7 & 1
é T rue.
Simplesmente mude n & 1
para n & 2
qual 2 representa 0010
em Binário e assim por diante.
Sugiro usar notação hexadecimal se você é iniciante em operações bit a bit
return n & 1;
>> return n & 0x01;
.