Comment puis-je vérifier si un entier est pair ou impair? [fermé]

Comment puis-je vérifier si un nombre est pair ou impair en C?

193
demandé sur ruakh 2008-10-02 09:00:08

30 réponses

utilisez l'opérateur modulo (%) pour vérifier s'il y a un reste en divisant par 2:

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

quelques personnes ont critiqué ma réponse ci-dessus disant que l'utilisation de x & 1 est" plus rapide "ou"plus efficace". Je ne crois pas que cela soit le cas.

par curiosité, j'ai créé deux programmes de cas de test insignifiants:

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

je les ai ensuite compilées avec gcc 4.1.3 sur une de mes machines 5 fois:

  • sans options d'optimisation.
  • Avec-O
  • Avec -Os
  • - O2
  • Avec-O3

j'ai examiné la sortie d'assemblage de chaque compilation (en utilisant gcc-S) et j'ai trouvé que dans chaque cas, la sortie pour et.c et modulo.c étaient identiques (les deux ont utilisé l'instruction andl $1, %eax). Je doute, c'est une "nouvelle" fonctionnalité, et je pense qu'elle remonte à versions anciennes. Je doute également que n'importe quel compilateur moderne (fait dans les 20 dernières années) non-arcane, commercial ou open source, manque une telle optimisation. Je voudrais tester sur d'autres compilateurs, mais je n'ai pas disponibles pour le moment.

si quelqu'un d'autre voudrait tester d'autres compilateurs et/ou cibles de plate-forme, et obtient un résultat différent, je serais très intéressé de savoir.

enfin, la version modulo est garantie par la norme pour travailler si le nombre entier est positif, négatif ou zéro, indépendamment de la représentation de l'implémentation des nombres entiers signés. L'opération de bits et la version n'est pas. Oui, je me rends compte que le complément de two est un peu omniprésent, donc ce n'est pas vraiment un problème.

450
répondu Chris 2008-10-02 15:21:58

vous êtes trop efficaces. Ce que vous voulez vraiment, c'est:

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

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

  return odd;
}

, répétez pour isEven .

bien sûr, ça ne marche pas pour les nombres négatifs. Mais avec brio vient le sacrifice...

209
répondu SCdF 2016-07-26 03:21:18

utiliser l'arithmétique des bits:

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

c'est plus rapide que d'utiliser la division ou le module.

97
répondu Adam Pierce 2008-10-02 05:01:36

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

[Blague mode="off"]

EDIT: Ajout de la confusion des valeurs de l'enum.

36
répondu Sklivvz 2008-10-02 16:25:11

en réponse à ffpf - j'ai eu exactement le même argument avec un collègue il y a des années, et la réponse est Non , il ne fonctionne pas avec des nombres négatifs.

la norme C stipule que les nombres négatifs peuvent être représentés de trois façons:

  • complément 2
  • complément de l'un
  • signe et magnitude

vérification comme ceci:

isEven = (x & 1);

fonctionnera pour le complément de 2 et la représentation du signe et de la magnitude, mais pas pour le complément de 1.

Cependant, je crois que la suite va travailler pour tous les cas:

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

merci à ffpf pour avoir souligné que la boîte de texte mangeait tout après mon moins que le caractère!

16
répondu Andrew Edgecombe 2017-05-23 10:31:26

une belle est:

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

noter que cette méthode utilise la récursion de la queue impliquant deux fonctions. Il peut être mis en œuvre efficacement (transformé en boucle de type while/until of) Si votre compilateur prend en charge la récursion de la queue comme un compilateur Scheme. Dans ce cas, la pile ne doit pas déborder !

14
répondu Pierre 2014-03-03 20:19:17

un nombre est même si, divisé par deux, le reste est 0. Un nombre est impair si, divisé par 2, le reste est 1.

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

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

les méthodes sont géniales!

11
répondu jjnguy 2010-09-01 16:14:41
i % 2 == 0
8
répondu Mark Cidade 2008-10-02 05:01:11

je dirais juste de le diviser par 2 et s'il y a un reste de 0, c'est égal, sinon c'est bizarre.

utilisant le module (%) rend cela facile.

par exemple. 4 % 2 = 0 donc 4 est pair 5% 2 = 1 donc 5 est impair

7
répondu Jarod Elliott 2008-10-02 05:01:01

une autre solution au problème

(les enfants sont invités à voter)

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

  }
  return half1 == half2;
}
6
répondu eugensk00 2008-10-02 11:14:27

je construirais une table des parités (0 si même 1 si Impair) des entiers (donc on pourrait faire une recherche :D) , mais gcc ne me laissera pas faire des tableaux de telles tailles:

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

donc recourons plutôt à la définition mathématique de pair et Impair à la place.

Un entier n est pair s'il existe un entier k tel que n = 2k.

un entier n est impair s'il existe un entier k tel que n = 2k + 1.

voici le code pour ça:

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

soit c-entiers les valeurs possibles de int dans une compilation C donnée. (Notez que C-nombres entiers est un sous-ensemble des nombres entiers.)

maintenant, on pourrait s'inquiéter que pour un n donné dans C-entiers que l'entier correspondant k pourrait ne pas exister dans C-entiers. Mais avec un peu de preuve, il est peut être démontré que, pour tous entiers n, |n| <= |2n| (*), où |n| est "n si n est positif et -n autrement." En d'autres termes, pour tous les n dans les entiers au moins un des suivants tient (exactement soit les cas (1 et 2) ou les cas (3 et 4) en fait, mais je ne vais pas le prouver ici):

Case 1: n < = 2n.

cas 2: - n < = - 2n.

Case 3: - n < = 2n.

Case 4: n < = - 2n.

prend maintenant 2k= N. (Un tel k existe si n est pair, mais je ne le prouverai pas ici. Si n est même pas la boucle en even ne revient pas tôt de toute façon, donc ça n'a pas d'importance.) Mais cela implique k < n Si n Non 0 par ( * ) et le fait (encore une fois non prouvé ici) que pour tous m, z dans les entiers 2m = z implique z pas égal à m donné m n'est pas 0. Dans le cas n est 0, 2*0 = 0 donc 0 est même nous sommes faits (si n = 0 puis 0 est dans C-entiers parce que n est dans C-entier dans la fonction even , donc k = 0 est dans C-entiers). Ainsi, tel un k dans C-entiers existe pour n dans C-entiers si n est pair.

A un argument similaire montre que si n est impair, il existe un k dans les entiers C tel que n = 2k + 1.

D'où les fonctions even et odd présentées ici fonctionneront correctement pour tous les entiers C.

6
répondu Thomas Eding 2010-02-27 02:20:47
// C#
bool isEven = ((i % 2) == 0);
5
répondu Michael Petrotta 2008-10-02 05:02:06

Comme certaines personnes ont posté, il y a de nombreuses façons de le faire. Selon ce site web , la voie la plus rapide est l'opérateur de module:

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

cependant, voici quelques autre code qui a été marqué au banc par l'auteur qui a couru plus lent que l'opération de module commun ci-dessus:

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

combien de personnes connaissaient même les mathématiques de .Système.Méthode DivRem ou pourquoi auraient-ils l'utiliser??

5
répondu Do What You Love 2014-07-09 08:41:43

Voici une réponse 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();
}
4
répondu Thomas Eding 2012-07-19 12:25:17

essayez ceci: return (((a>>1)<<1) == a)

exemple:

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

b     =  10011100
-----------------
b>>1 --> 01001110
b<<1 --> 10011100
4
répondu Kiril Aleksandrov 2015-08-10 19:58:43

en lisant cette discussion plutôt divertissante, je me suis souvenu que j'avais une fonction sensible au temps qui testait les nombres impairs et pairs à l'intérieur de la boucle principale. C'est une fonction de puissance entière, posté ailleurs sur StackOverflow, comme suit. Les points de repère étaient assez surprenants. Au moins dans cette fonction du monde réel, modulo est plus lent , et de façon significative. le gagnant, par une large marge, nécessitant 67% du temps de modulo, est un ou ( | ) approche , et est nulle part ailleurs sur cette page.

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

pour 300 millions de boucles, les temps de référence sont les suivants.

3.962 | et le masque approche

4.851 l' & approche

5.850 l' % approche

pour les gens qui pensent que la théorie, ou une liste de langage de l'Assemblée, règle des arguments comme ceux-ci, ce devrait être un conte de mise en garde. Il y a plus de choses dans le ciel et sur la terre, Horatio, que dans ta philosophie.

4
répondu 2016-03-05 01:38:01

il s'agit d'un suivi à la discussion avec @RocketRoy concernant sa réponse , mais il pourrait être utile à quiconque veut comparer ces résultats.

tl;dr D'après ce que j'ai vu, L'approche de Roy ( (0xFFFFFFFF == (x | 0xFFFFFFFE) ) n'est pas complètement optimisée à x & 1 comme l'approche mod , mais dans la pratique les temps de fonctionnement devraient être égaux dans tous les cas.

donc, d'abord j'ai comparé le sortie compilée en utilisant Compiler Explorer :

fonctions testées:

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 with-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 avec-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

Chapeaux bas de Bruit, elle s'est rendu compte que tous les trois cas ont un fonctionnement identique. Cependant, L'approche de Roy n'est pas optimisée dans GCC, donc YMMV.

c'est similaire avec Visual Studio; en inspectant la version de démontage x64 (VS2015) pour ces trois fonctions, j'ai pu voir que la partie de comparaison est égale pour" mod "et" et "cases, et légèrement plus grande pour le Roy's" ou "case:

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

cependant, après avoir exécuté un benchmark réel pour comparer ces trois options (simple mod, bitwise or, bitwise and), les résultats ont été complètement égaux (encore une fois, Visual Studio 2005 x86/x64, Version construire, pas de débogueur).

L'assemblage de libération

utilise l'instruction test pour les boîtiers and et mod , tandis que le boîtier de Roy utilise l'approche cmp eax,0FFFFFFFFh , mais il est fortement déroulé et optimisé de sorte qu'il n'y a pas de différence dans la pratique.

mes résultats après 20 passages (i7 3610QM, Windows 10 power plan réglé à haute 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%)

la différence entre ces options est inférieure à De 0,3%, c'est assez évident que l'assemblée est égale dans tous les cas.

voici le code si quelqu'un veut essayer, avec une mise en garde que je ne l'ai testé que sur Windows (cochez la #if LINUX conditionnel pour la get_time définition et mettre en œuvre si nécessaire, prise de cette réponse ).

#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;
}
4
répondu Lou 2017-05-23 11:54:44

je sais que c'est juste du sucre syntaxique et seulement applicable en .net mais qu'en est-il de la méthode d'extension...

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

Maintenant vous pouvez faire ce qui suit""

int i = 5;
if (i.IsOdd())
{
    // Do something...
}
3
répondu rudigrobler 2008-10-02 13:01:23

dans la "catégorie créative mais déroutante" j'offre:

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

une variante sur ce thème qui est spécifique à 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
    }
}
3
répondu DocMax 2008-10-08 14:16:42

la méthode bitwise dépend de la représentation interne de l'entier. Modulo fonctionne partout où il y a un opérateur modulo. Par exemple, certains systèmes utilisent les bits de bas niveau pour le tagging (comme les langages dynamiques), donc le x & 1 brut ne fonctionnera pas dans ce cas.

2
répondu Will Hartung 2008-10-02 05:53:51

IsOdd (int x) { return true;}

preuve d'exactitude - considérez l'ensemble de tous les entiers positifs et supposons qu'il y a un ensemble non vide d'entiers qui ne sont pas impairs. Parce que les entiers positifs sont bien ordonnés, il y aura un plus petit nombre pas Impair, qui en lui-même est assez Impair, donc clairement que le nombre ne peut pas être dans l'ensemble. Par conséquent, cet ensemble ne peut pas être non vide. Répéter pour les nombres entiers négatifs, sauf chercher le plus grand nombre pas Impair.

2
répondu plinth 2008-10-02 15:03:11

Portable:

i % 2 ? odd : even;

Portables:

i & 1 ? odd : even;

i << (BITS_PER_INT - 1) ? odd : even;
2
répondu ilitirit 2008-10-02 15:08:27
int isOdd(int i){
  return(i % 2);
}

fait.

1
répondu None 2008-10-13 15:50:31

pour donner plus de détails sur la méthode de l'opérateur bitwise pour ceux d'entre nous qui n'ont pas fait beaucoup d'algèbre booléenne au cours de nos études, voici une explication. Probablement pas d'une grande utilité pour L'OP, mais j'ai eu envie de dire clairement pourquoi nombre & 1 fonctionne.

s'il vous plaît noter comme quelqu'un a répondu ci-dessus, la façon dont les nombres négatifs sont représentés peut arrêter cette méthode de travail. En fait, il peut même briser la méthode de l'opérateur modulo aussi, puisque chaque langue peut différer dans la façon dont il traite négatif opérandes.

cependant si vous savez que le nombre sera toujours positif, cela fonctionne bien.

comme Tooony ci-dessus fait le point que seul le dernier chiffre en binaire (et denary) est important.

une logique booléenne et une porte dicte que les deux entrées doivent être une 1 (ou haute tension) pour que 1 soit retourné.

1 & 0 = 0.

0 & 1 = 0.

0 & 0 = 0.

1 & 1 = 1.

si vous représentez n'importe quel nombre comme binaire (j'ai employé une représentation de 8 bits ici), les nombres impairs ont 1 à la fin, même les nombres ont 0.

par exemple:

1 = 00000001

2 = 00000010

3 = 00000011

4 = 00000100

si vous prenez n'importe quel nombre et utilisez bitwise et (& en java) it par 1 it renvoie 00000001, = 1 ce qui signifie que le nombre est impair. Ou 00000000 = 0, ce qui signifie que le nombre est pair.

e. g

c'est bizarre?

1 & 1 =

00000001 &

00000001 =

00000001 <- Impair

2& 1 =

00000010 &

00000001 =

00000000 < - Pair

54 & 1 =

00000001 &

00110110 =

00000000 < - Pair

C'est pourquoi cela fonctionne:

if(number & 1){

   //Number is odd

} else {

   //Number is even
}

Désolé si c'est redondant.

1
répondu Astridax 2013-09-11 14:52:35

nombre parité Zéro / Zéro http://tinyurl.com/oexhr3k

séquence de code 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))

sortie:

   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
1
répondu 2015-10-20 13:40:53
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);
}
1
répondu Omar Faruk 2017-08-01 08:33:28

Pour le bien de la discussion...

il suffit de regarder le dernier chiffre d'un numéro donné pour voir s'il est pair ou impair. Signed, unsigned, positif, négatif, ils sont tout de même en ce qui concerne cela. Donc cela devrait fonctionner tout autour: -

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 clé ici est dans la troisième ligne de code, l'opérateur de division effectue une division entière, de sorte que le résultat manque la fraction du résultat. Ainsi par exemple 222 / 10 donnera 22. Puis multipliez-le à nouveau avec 10 et vous avez 220. Soustrayez cela de l'original 222 et vous vous retrouvez avec 2, qui par magie est le même nombre que le dernier chiffre dans le nombre original. ;-) Les parenthèses sont là pour nous rappeler à l'ordre le calcul est fait en. Faites d'abord la division et la multiplication, puis soustrayez le résultat du nombre original. Nous pourrions les exclure, car la priorité est plus grande pour la division et la multiplication que pour la soustraction, mais cela nous donne un code "plus lisible".

nous pourrions rendre tout cela complètement illisible si nous le voulions. Cela ne ferait aucune différence pour un compilateur moderne: -

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

mais cela rendrait le code beaucoup plus difficile à maintenir à l'avenir. Imaginez que vous souhaitez modifier le texte pour les nombres impairs "n'est même pas". Par la suite, quelqu'un d'autre veut savoir quels changements vous avez faits et effectuer un svn diff ou similaire...

si vous n'êtes pas inquiet au sujet de la portabilité, mais plus au sujet de la vitesse, vous pourriez avoir un coup d'oeil au moins significatif. Si ce bit est mis à 1, il est un nombre impair, si c'est 0 c'est un nombre pair. Sur un petit système endian, comme L'architecture x86 D'Intel, ce serait quelque chose comme ceci: -

if (iToTest & 1) {
  // Even
} else {
  // Odd
}
0
répondu Tooony 2008-10-02 16:02:04

si vous voulez être efficace, utilisez des opérateurs bitwise ( x & 1 ), mais si vous voulez être lisible, utilisez modulo 2 ( x % 2 )

0
répondu Vihung 2008-10-03 11:12:14

vérifier pair ou Impair est une tâche simple.

nous savons que tout nombre exactement divisible par 2 est impair.

nous avons juste besoin de vérifier la divisibilité de n'importe quel nombre et pour vérifier la divisibilité nous utilisons % opérateur

contrôle Pair Impair en utilisant sinon

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

C programme pour vérifier pair ou impair en utilisant if else

utilisant l'opérateur conditionnel / ternaire

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

C Programme pour vérifier pair ou impair en utilisant l'opérateur conditionnel .

utilisant l'opérateur Bitwise

if(num & 1)  
{
    printf("Odd");
}
else 
{
    printf("Even");
}
0
répondu Pankaj Prakash 2017-08-28 13:58:04

+66% plus rapide > !(i%2) / i%2 == 0

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

le code vérifie le dernier bit de l'entier s'il est 1 en binaire

explication

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

Notice le plus à droite bit est toujours 1 pour Impair nombres.

le & au niveau du bit ET de l'opérateur vérifie la droite peu dans notre retour ligne 1

pensez-y comme vrai & faux

quand on compare n avec 1 qui signifie 0001 en binaire (le nombre de zéros n'a pas d'importance).

alors imaginons que nous avons l'entier n avec une taille de 1 octet.

il serait représenté par 8 bits / 8 chiffres binaires.

si l'int n était 7 et nous le comparons avec 1 , c'est comme

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

qui F signifie faux et T pour vrai.

Il compare seulement le plus à droite si les deux sont vrais. Donc, automatiquement 7 & 1 est t rue.

Que faire si je veux vérifier le bit avant le plus à droite?

change simplement n & 1 en n & 2 qui 2 représente 0010 en binaire et ainsi de suite.

je suggère d'utiliser la notation hexadécimale si vous êtes un débutant aux opérations bitwise

return n & 1; > > return n & 0x01; .

0
répondu X Stylish 2018-04-28 03:55:58