¿Cómo puedo verificar si un número dado es par o impar en C?
¿Cómo puedo verificar si un número dado es par o impar en C?
Respuestas:
Use el operador de módulo (%) para verificar si hay un resto al dividir por 2:
if (x % 2) { /* x is odd */ }
Algunas personas han criticado mi respuesta anterior afirmando que usar x & 1 es "más rápido" o "más eficiente". No creo que este sea el caso.
Por curiosidad, creé dos programas triviales de casos de prueba:
/* 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;
}
Luego los compilé con gcc 4.1.3 en una de mis máquinas 5 veces diferentes:
Examiné la salida del ensamblaje de cada compilación (usando gcc -S) y descubrí que en cada caso, la salida para and.c y modulo.c eran idénticas (ambas usaban la instrucción andl $ 1,% eax). Dudo que esta sea una característica "nueva", y sospecho que se remonta a versiones antiguas. También dudo que cualquier compilador moderno (hecho en los últimos 20 años) no arcano, comercial o de código abierto, carezca de tal optimización. Probaría en otros compiladores, pero no tengo ninguno disponible en este momento.
Si a alguien más le gustaría probar otros compiladores y / o objetivos de plataforma, y obtiene un resultado diferente, estaría muy interesado en saberlo.
Finalmente, la versión del módulo está garantizada por el estándar para trabajar si el entero es positivo, negativo o cero, independientemente de la representación de la implementación de enteros con signo. La versión bit a bit no lo es. Sí, me doy cuenta de que el complemento de dos es algo omnipresente, por lo que esto no es realmente un problema.
Ustedes son muuuuuuy demasiado eficientes. Lo que realmente quieres es:
public boolean isOdd(int num) {
int i = 0;
boolean odd = false;
while (i != num) {
odd = !odd;
i = i + 1;
}
return odd;
}
Repita para isEven
.
Por supuesto, eso no funciona para números negativos. Pero con el brillo viene el sacrificio ...
Use aritmética de bits:
if((x & 1) == 0)
printf("EVEN!\n");
else
printf("ODD!\n");
Esto es más rápido que usar división o módulo.
[Modo broma = "activado"]
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 broma = "apagado"]
EDITAR: Se agregaron valores confusos a la enumeración.
En respuesta a ffpf : tuve exactamente el mismo argumento con un colega hace años, y la respuesta es no , no funciona con números negativos.
El estándar C estipula que los números negativos se pueden representar de 3 maneras:
Comprobando así:
isEven = (x & 1);
funcionará para el complemento de 2 y la representación de signo y magnitud, pero no para el complemento de 1.
Sin embargo, creo que lo siguiente funcionará para todos los casos:
isEven = (x & 1) ^ ((-1 & 1) | ((x < 0) ? 0 : 1)));
¡Gracias a ffpf por señalar que el cuadro de texto estaba comiendo todo después de mi carácter menos que!
Una buena es:
/*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
}
Tenga en cuenta que este método utiliza la recursividad de cola que involucra dos funciones. Se puede implementar de manera eficiente (se convierte en un ciclo while / while) si su compilador admite la recursividad de cola como un compilador de Scheme. ¡En este caso, la pila no debería desbordarse!
Un número es par si, cuando se divide por dos, el resto es 0. Un número es impar si, cuando se divide por 2, el resto es 1.
// Java
public static boolean isOdd(int num){
return num % 2 != 0;
}
/* C */
int isOdd(int num){
return num % 2;
}
Los métodos son geniales!
i % 2 == 0
Yo diría simplemente dividirlo por 2 y si hay un resto 0, es par, de lo contrario es impar.
Usar el módulo (%) lo hace fácil.
p.ej. 4% 2 = 0 por lo tanto 4 es par 5% 2 = 1 por lo tanto 5 es impar
Una solución más al problema
(los niños pueden 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;
}
Construiría una tabla de las paridades (0 si incluso 1 si es impar) de los enteros (para que uno pueda hacer una búsqueda: D), pero gcc no me deja hacer matrices de tales tamaños:
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];
}
Entonces, recurramos a la definición matemática de pares e impares.
Un número entero n es incluso si existe un número entero k tal que n = 2k.
Un número entero n es impar si existe un número entero k tal que n = 2k + 1.
Aquí está el código para ello:
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;
}
Deje que los enteros en C denoten los posibles valores de int
en una compilación de C dada. (Tenga en cuenta que los enteros en C son un subconjunto de los enteros).
Ahora, uno podría preocuparse de que para un n dado en C-enteros, el entero k correspondiente podría no existir dentro de C-enteros. Pero con una pequeña prueba se puede demostrar que para todos los enteros n, | n | <= | 2n | (*), donde | n | es "n si n es positivo y -n de lo contrario". En otras palabras, para todos los n en enteros, al menos una de las siguientes retenciones (exactamente los casos (1 y 2) o los casos (3 y 4) de hecho, pero no lo probaré aquí):
Caso 1: n <= 2n.
Caso 2: -n <= -2n.
Caso 3: -n <= 2n.
Caso 4: n <= -2n.
Ahora toma 2k = n. (Tal ak existe si n es par, pero no lo probaré aquí. Si n no lo es, entonces el ciclo even
no regresa temprano de todos modos, por lo que no importa). Pero esto implica k <n si n no 0 por (*) y el hecho (nuevamente no comprobado aquí) de que para todos m, z en enteros 2m = z implica z no igual a m dado m no es 0. En el caso n es 0, 2 * 0 = 0 así que 0 es incluso que hemos terminado (si n = 0, entonces 0 está en C-enteros porque n está en C-entero en la función even
, por lo tanto, k = 0 está en C-enteros). Así, tal ak en C-enteros existe para n en C-enteros si n es par.
Un argumento similar muestra que si n es impar, existe ak en enteros en C tal que n = 2k + 1.
Por lo tanto, las funciones even
y las odd
presentadas aquí funcionarán correctamente para todos los C-enteros.
i % 2
es mucho más pequeño y probablemente más eficiente.
%2
funciona para todos los enteros.
// C#
bool isEven = ((i % 2) == 0);
typedef
o #define
o algo así.
Aquí hay una respuesta en 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();
}
Prueba esto: return (((a>>1)<<1) == a)
Ejemplo:
a = 10101011
-----------------
a>>1 --> 01010101
a<<1 --> 10101010
b = 10011100
-----------------
b>>1 --> 01001110
b<<1 --> 10011100
Al leer esta discusión bastante entretenida, recordé que tenía una función sensible al tiempo en el mundo real que evaluaba los números pares e impares dentro del bucle principal. Es una función de potencia entera, publicada en otro lugar en StackOverflow, de la siguiente manera. Los puntos de referencia fueron bastante sorprendentes. Al menos en esta función del mundo real, el módulo es más lento y significativamente más. El ganador, por un amplio margen, que requiere el 67% del tiempo del módulo, es un enfoque o (|) , y no se encuentra en ninguna otra parte de esta 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 millones de bucles, los tiempos de referencia son los siguientes.
3.962 el | y enfoque de máscara
4.851 el enfoque
5.850 el enfoque%
Para las personas que piensan que la teoría, o una lista de lenguaje ensamblador, resuelve argumentos como estos, esta debería ser una historia de advertencia. Horatio, hay más cosas en el cielo y en la tierra de las que sueñas en tu filosofía.
unsigned x
como x = x >> 1;
es el comportamiento definido por la implementación cuando x < 0
. No está claro por qué x
y OrMask
difiere en tipo. Suficientemente simple para reescribir usando una while(x)
prueba.
% 2
caso utilizando bitwise &
. Acabo de probar esto y los resultados son completamente iguales (VS2015, versiones de lanzamiento con todas las optimizaciones, tanto x86 como x64). La respuesta aceptada también establece esto para GCC (escrito en 2008).
or
sería más rápido que un and
es altamente improbable en cualquier plataforma / compilador. Incluso si hubiera un combo de plataforma / compilador tan extraño (y no haya publicado ni eso ni el código utilizado para realizar el punto de referencia), depender de que otros compiladores se comporten de la misma manera sería una mala apuesta de optimización. Entonces, como escribí, me pregunto en qué plataforma / compilador se probó esto , porque estoy casi seguro de que no se midió correctamente.
Este es un seguimiento de la discusión con @RocketRoy con respecto a su respuesta , pero podría ser útil para cualquiera que quiera comparar estos resultados.
tl; dr Por lo que he visto, el enfoque de Roy ( (0xFFFFFFFF == (x | 0xFFFFFFFE)
) no está completamente optimizado x & 1
como el mod
enfoque, pero en la práctica los tiempos de ejecución deberían ser iguales en todos los casos.
Entonces, primero comparé la salida compilada usando Compiler Explorer :
Funciones probadas:
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 con -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 con -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
Gracias a CLang, se dio cuenta de que los tres casos son funcionalmente iguales. Sin embargo, el enfoque de Roy no está optimizado en GCC, por lo que YMMV.
Es similar con Visual Studio; Al inspeccionar la versión de desensamblaje x64 (VS2015) para estas tres funciones, pude ver que la parte de comparación es igual para "mod" y "y" casos, y un poco más grande para el caso de Roy "o":
// 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)
Sin embargo, después de ejecutar un punto de referencia real para comparar estas tres opciones (mod simple, bit a bit o bit a bit y), los resultados fueron completamente iguales (de nuevo, Visual Studio 2005 x86 / x64, versión de compilación, sin depurador adjunto).
El ensamblaje de lanzamiento usa las test
instrucciones and
y los mod
casos, mientras que el caso de Roy usa el cmp eax,0FFFFFFFFh
enfoque, pero está muy desenrollado y optimizado, por lo que no hay diferencia en la práctica.
Mis resultados después de 20 ejecuciones (i7 3610QM, plan de energía de Windows 10 establecido en Alto rendimiento):
[Prueba: Mod 2 simple] TIEMPO PROMEDIO: 689.29 ms (Diferencia relativa: + 0.000%) [Prueba: Bitwise o] TIEMPO PROMEDIO: 689,63 ms (Diferencia relativa: + 0,048%) [Prueba: a nivel de bits y] TIEMPO PROMEDIO: 687,80 ms (diferencia relativa: -0,217%)
La diferencia entre estas opciones es inferior al 0.3%, por lo que es bastante obvio que el ensamblaje es igual en todos los casos.
Aquí está el código si alguien quiere probar, con una advertencia de que solo lo probé en Windows (verifique el #if LINUX
condicional para la get_time
definición e impleméntelo si es necesario, tomado de esta respuesta ).
#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;
}
Sé que esto es solo azúcar sintáctico y solo aplicable en .net, pero qué pasa con el método de extensión ...
public static class RudiGroblerExtensions
{
public static bool IsOdd(this int i)
{
return ((i % 2) != 0);
}
}
Ahora puedes hacer lo siguiente
int i = 5;
if (i.IsOdd())
{
// Do something...
}
En la "categoría creativa pero confusa" ofrezco:
int isOdd(int n) { return n ^ n * n ? isOdd(n * n) : n; }
Una variante sobre este tema que es específica de 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
}
}
El método bit a bit depende de la representación interna del número entero. El módulo funcionará en cualquier lugar donde haya un operador de módulo. Por ejemplo, algunos sistemas realmente usan los bits de bajo nivel para el etiquetado (como los lenguajes dinámicos), por lo que el x & 1 sin procesar en realidad no funcionará en ese caso.
IsOdd (int x) {return true; }
Prueba de corrección: considere el conjunto de todos los enteros positivos y suponga que hay un conjunto de enteros no vacío que no es impar. Debido a que los enteros positivos están bien ordenados, habrá un número más pequeño, no impar, que en sí mismo es bastante extraño, por lo que claramente ese número no puede estar en el conjunto. Por lo tanto, este conjunto no puede estar no vacío. Repita para enteros negativos, excepto busque el mayor número no impar.
Como algunas personas han publicado, hay numerosas formas de hacerlo. Según este sitio web , la forma más rápida es el operador de módulo:
if (x % 2 == 0)
total += 1; //even number
else
total -= 1; //odd number
Sin embargo, aquí hay otro código que fue marcado por el autor que corrió más lento que la operación de módulo común anterior:
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
¿Cuántas personas sabían del método Math.System.DivRem o por qué lo usarían?
Para dar más detalles sobre el método del operador bit a bit para aquellos de nosotros que no hicimos mucho álgebra booleana durante nuestros estudios, aquí hay una explicación. Probablemente no sea de mucha utilidad para el OP, pero sentí que quería aclarar por qué NUMBER & 1 funciona.
Tenga en cuenta que, como alguien respondió anteriormente, la forma en que se representan los números negativos puede detener este método. De hecho, incluso puede romper el método del operador de módulo también, ya que cada idioma puede diferir en la forma en que trata los operandos negativos.
Sin embargo, si sabe que NUMBER siempre será positivo, esto funciona bien.
Como Tooony mencionó anteriormente, solo el último dígito en binario (y denario) es importante.
Una puerta AND lógica booleana dicta que ambas entradas deben ser 1 (o alto voltaje) para que 1 sea devuelto.
1 y 0 = 0.
0 y 1 = 0.
0 y 0 = 0.
1 y 1 = 1.
Si representa cualquier número como binario (he usado una representación de 8 bits aquí), los números impares tienen 1 al final, los números pares tienen 0.
Por ejemplo:
1 = 00000001
2 = 00000010
3 = 00000011
4 = 00000100
Si toma cualquier número y usa Y bit a bit (y en Java) por 1, devolverá 00000001, = 1, lo que significa que el número es impar. O 00000000 = 0, lo que significa que el número es par.
P.ej
¿Es impar?
1 y 1 =
00000001 y
00000001 =
00000001 <- impar
2 y 1 =
00000010 y
00000001 =
00000000 <- Par
54 y 1 =
00000001 y
00110110 =
00000000 <- Par
Por eso funciona esto:
if(number & 1){
//Number is odd
} else {
//Number is even
}
Lo siento si esto es redundante.
Número cero paridad | cero http://tinyurl.com/oexhr3k
Secuencia de código de 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))
Salida:
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 el bien de la discusión ...
Solo necesita mirar el último dígito en cualquier número dado para ver si es par o impar. Firmado, sin firmar, positivo, negativo: todos son iguales con respecto a esto. Entonces esto debería funcionar en todos los aspectos:
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);
}
}
La clave aquí está en la tercera línea de código, el operador de división realiza una división entera, por lo que al resultado le falta la parte fraccionaria del resultado. Entonces, por ejemplo, 222/10 dará 22 como resultado. Luego multiplícalo nuevamente por 10 y tendrás 220. Resta eso del 222 original y terminarás con 2, que por arte de magia es el mismo número que el último dígito en el número original. ;-) Los paréntesis están allí para recordarnos el orden en que se realiza el cálculo. Primero, haga la división y la multiplicación, luego reste el resultado del número original. Podríamos dejarlos fuera, ya que la prioridad es mayor para la división y la multiplicación que para la resta, pero esto nos da un código "más legible".
Podríamos hacerlo completamente ilegible si quisiéramos. No haría ninguna diferencia para un compilador moderno:
printf("%d%s\n",iToTest,0==(iToTest-iToTest/10*10)%2?" is even":" is odd");
Pero haría el código mucho más difícil de mantener en el futuro. Solo imagine que le gustaría cambiar el texto de los números impares a "no es par". Luego, otra persona más adelante quiere saber qué cambios realizó y realizar un svn diff o similar ...
Si no le preocupa la portabilidad, sino más bien la velocidad, puede echar un vistazo al bit menos significativo. Si ese bit se establece en 1, es un número impar, si es 0 es un número par. En un pequeño sistema endian, como la arquitectura x86 de Intel, sería algo como esto:
if (iToTest & 1) {
// Even
} else {
// Odd
}
Si quiere ser eficiente, use operadores bit a bit (x & 1
), pero si quiere ser legible use el módulo 2 ( x % 2
)
%
. Si quieres que sea legible, úsalo %
. Hmmm, veo un patrón aquí.
Verificar pares o impares es una tarea simple.
Sabemos que cualquier número exactamente divisible por 2 es un número par más impar.
Solo necesitamos verificar la divisibilidad de cualquier número y para verificar la divisibilidad usamos %
operador
Comprobando incluso impar usando si más
if(num%2 ==0)
{
printf("Even");
}
else
{
printf("Odd");
}
Programa C para verificar pares o impares usando si no
Uso del operador condicional / ternario
(num%2 ==0) printf("Even") : printf("Odd");
Programa C para verificar pares o impares usando el operador condicional .
Usando el operador Bitwise
if(num & 1)
{
printf("Odd");
}
else
{
printf("Even");
}
!(i%2) / i%2 == 0
int isOdd(int n)
{
return n & 1;
}
El código verifica el último bit del entero si es 1 en binario
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 el bit más a la derecha siempre es 1 para los números impares .
los & operador AND comprueba el bit más a la derecha en nuestro retorno de línea si se trata de 1
Cuando comparamos n con 1, lo que significa 0001
en binario (el número de ceros no importa).
entonces imaginemos que tenemos el número entero n con un tamaño de 1 byte.
Estaría representado por dígitos binarios de 8 bits / 8.
Si int n era 7 y lo comparamos con 1 , es 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
Cuál F significa falso y T significa verdadero.
Se compara solamente el bit más a la derecha si son ambas verdaderas. Entonces, automágicamente
7 & 1
es T rue.
Simplemente cambie n & 1
a n & 2
qué 2 representa 0010
en binario y así sucesivamente.
Sugiero usar la notación hexadecimal si eres un principiante en operaciones bit a bit
return n & 1;
>> return n & 0x01;
.