Comment puis-je vérifier si un nombre donné est pair ou impair en C ?
Pour Java, cela doit être : if (x % 2 == 0) { /* x est impair */ } Les entiers n'étant pas automatiquement traités comme des booléens dans les instructions if.
Comment puis-je vérifier si un nombre donné est pair ou impair en C ?
Utilisez l'opérateur modulo (%) pour vérifier s'il y a un reste lorsqu'on divise par 2 :
if (x % 2) { /* x is odd */ }
Quelques personnes ont critiqué ma réponse ci-dessus en déclarant que l'utilisation de x & 1 est "plus rapide" ou "plus efficace". Je ne pense pas que ce soit le cas.
Par curiosité, j'ai créé deux programmes de test triviaux :
/* 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és avec gcc 4.1.3 sur l'une de mes machines 5 fois différentes :
J'ai examiné la sortie de l'assemblage de chaque compilation (en utilisant gcc -S) et j'ai constaté que dans chaque cas, la sortie de and.c et de modulo.c était identique (ils utilisaient tous deux l'instruction andl $1, %eax). Je doute que ce soit une "nouvelle" fonctionnalité, et je soupçonne que cela remonte à d'anciennes versions. Je doute également qu'un compilateur moderne (fait au cours des 20 dernières années) non-arcane, commercial ou open source, manque d'une telle optimisation. Je testerais bien sur d'autres compilateurs, mais je n'en ai aucun de disponible pour le moment.
Si quelqu'un d'autre souhaite tester d'autres compilateurs et/ou d'autres plates-formes cibles et obtient un résultat différent, je serais très intéressé de le savoir.
Enfin, la version modulo est garanti par la norme pour travailler si l'entier est positif, négatif ou nul, quelle que soit la représentation des entiers signés de l'implémentation. La version bitwise-and ne l'est pas. Oui, je réalise que le complément à deux est quelque peu omniprésent, donc ce n'est pas vraiment un problème.
Pour Java, cela doit être : if (x % 2 == 0) { /* x est impair */ } Les entiers n'étant pas automatiquement traités comme des booléens dans les instructions if.
La question demandait spécifiquement comment le faire en C, j'ai donc répondu en C, bien que chustar ait mentionné qu'il ne pouvait pas trouver comment le faire en Java. Je n'ai pas prétendu ou laissé entendre que c'était une réponse en Java, je ne connais pas Java. Je pense que je viens de recevoir mon premier vote négatif et je ne sais pas pourquoi. Mais bon.
Je dirais, si (x % 2 != 0) { /* x est impair */ }, mais qui sait. Je ne connais pas non plus la java.
Vous êtes beaucoup 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 l'intelligence vient le sacrifice...
Je dois être d'accord... intéressant, mais un peu dément. Si c'était slashdot, vous auriez un upvote pour l'humour. Je ne peux pas recommander cette solution cependant :)
Si vous lanciez une exception d'argument sur les valeurs négatives, et si vous indiquiez dans la documentation que cette fonction est O(N), alors je serais tout à fait d'accord avec cela.
Je ne pense pas qu'il soit juste de dire que c'est plus rapide que d'utiliser la division ou le modulus. La norme C ne dit rien sur les performances des opérateurs, et tout compilateur décent produira un code rapide pour l'un ou l'autre. Personnellement, je choisirais l'idiome qui communique mon intention, et % semble plus approprié ici.
Je suis d'accord avec Chris Young - je crois que n'importe quel compilateur C/C++ moderne réduira l'opération "% 2" à un test de bit. Au moins pour les constructions non déboguées.
[Joke mode="on"]
public enum Evenness
{
Unknown = 0,
Even = 1,
Odd = 2
}
public static Evenness AnalyzeEvenness(object o)
{
if (o == null)
return Evenness.Unknown;
string foo = o.ToString();
if (String.IsNullOrEmpty(foo))
return Evenness.Unknown;
char bar = foo[foo.Length - 1];
switch (bar)
{
case '0':
case '2':
case '4':
case '6':
case '8':
return Evenness.Even;
case '1':
case '3':
case '5':
case '7':
case '9':
return Evenness.Odd;
default:
return Evenness.Unknown;
}
}
[Joke mode="off"]
EDIT : Ajout de valeurs déroutantes à l'enum.
Wow... c'est plus dément que la solution de SCdF ! Kudos ! Pas d'upvote cependant... je ne peux pas la recommander. Mais merci pour l'humour !
L'avantage de cette approche est qu'elle fonctionne avec plus que des chiffres. En outre, si vous remplacez la ligne suivante : char bar = foo[foo.Length - 1] ; par la suivante : double bar = Char.GetNumericValue(foo[foo.Length - 1]) ; cela fonctionnera avec n'importe quel système numérique.
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 la suivante pas de il ne fonctionne pas avec les nombres négatifs.
La norme C stipule que les nombres négatifs peuvent être représentés de 3 façons :
En vérifiant comme ça :
isEven = (x & 1);
fonctionnera pour le complément à 2 et la représentation du signe et de la magnitude, mais pas pour le complément à 1.
Cependant, je pense que ce qui suit fonctionnera dans tous les cas :
isEven = (x & 1) ^ ((-1 & 1) | ((x < 0) ? 0 : 1)));
Merci à ffpf de m'avoir fait remarquer que la zone de texte mangeait tout ce qui se trouvait après mon caractère moins que !
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
5 votes
La version qui utilise le bitwise et (&) est beaucoup plus efficace que la version modulo (%). Vous devriez changer celle que vous avez choisie comme réponse correcte.
6 votes
Peu probable que cela ait de l'importance - l'argument est une constante. Facile pour l'optimiseur
1 votes
Avez-vous fait un benchmark ? Les performances des différentes constructions dépendent fortement du compilateur, de votre CPU et d'autres effets secondaires.
2 votes
La lisibilité entre également en ligne de compte.
0 votes
L'opérateur modulo est beaucoup plus portable vers d'autres langages (en particulier les langages faiblement typés). l'utilisation de l'opérateur bitwise est le type d'optimisation qui n'est vraiment pas susceptible d'affecter les performances.
2 votes
Dans les applications embarquées (le monde où je passe la plupart de mon temps de programmation), certains processeurs ont des unités arithmétiques très primitives et ne peuvent pas faire facilement des opérations de division/modulation. Pour cette raison, j'utilise généralement la méthode bitwise-and à la place. Cependant, sur le processeur d'un ordinateur de bureau moderne, ce ne sera pas le cas.
1 votes
Le fait que (%) ou (&) soit plus rapide ne dépend pas seulement du compilateur mais aussi de la machine. (On pourrait construire une machine qui a des opérations bitwise lentes mais qui a des opérations arithmétiques super rapides (relatives) pour le plaisir).
3 votes
Je n'ai jamais trouvé que l'opération du modulus était plus facile à comprendre. Lorsque j'ai eu pour la première fois besoin de déterminer le caractère pair ou impair, le masque bit à bit a été la première chose qui m'est venue à l'esprit. C'est assez naturel, puisque la façon dont nous avons tendance à le faire à la main est de regarder le chiffre le moins significatif pour voir s'il se trouve dans {0 2 4 6 8} ou {1 3 5 7 9}. Cela se traduit directement en regardant le bit le moins significatif pour voir s'il est 0 ou 1.
0 votes
Ni l'approche modulo, ni l'approche and ne sont optimales. Voir la soumission de code ci-dessous.
0 votes
Je pense que vous devriez changer votre choix de gagnant, car j'ai clairement démontré que ni l'approche % ni l'approche & ne répondent à votre critère "Comment puis-je vérifier au mieux...".
0 votes
Trouvez-le ici Programme pour vérifier le caractère pair ou impair en C