7
votes

Déterminer si un int est une puissance de 2 ou non dans une seule ligne

Dupliqué possible: strong>
Comment vérifier si un numéro est un pouvoir de 2 p>

J'ai fait le code suivant, mais cela ne fonctionne pas. Le compilateur donne une erreur pour une erreur manquante ) code> et d'expression syntaxe. Quelle est la procédence des opérateurs? De gauche à droite ou à droite à gauche? P>

#include <stdio.h>
#include <limits.h>
#include <math.h>
int main()
{
    int i, x = 256, y, flag;
    for (i = 0, flag = 0, y = 1; y<INT_MAX; if (flag) break, if (flag) printf("YES"), if(y == x) flag = 1, i++, y = pow(2,i));
    return 0;
}


10 commentaires

Il existe une solution très simple à ce problème.


Eww. Méchant. Pour la honte.


@Fahad: Vous n'avez clairement pas lu la question et les réponses auxquelles j'ai lié.


@FAHAD: La réponse votée la plus élevée à ce lien fonctionne dans une ligne si vous ne l'enveloppez pas dans une fonction. Ni est une "ligne" une unité fondamentale du code C: laissez simplement sortir les nouvelles lignes et tout entre les directives de préprocesseur convient à «une ligne».


@James, le lien fourni est une excellente solution, pas que j'ai la chance de la lire et de le comprendre. Bonne trouvaille :)


Quelqu'un peut-il m'aider avec mon code :(?


@james: merci pour le lien :)


Étant donné que la vraie question ici est le diagnostic de la boucle Formée mal, si la question doit être modifiée pour rendre la puissance de deux critères de test pour "où est l'erreur de syntaxe et pourquoi?" Je voterais à repiquer dans ce cas.


@ Rberteig, je serais très reconnaissant si vous modifiez le code.


Cette question n'est pas un duplicata de la question liée. La question liée concerne le C #, qui est une langue complètement différente.


4 Réponses :


25
votes
for( i=0, flag=0, y=1;
     y<INT_MAX;      
     if(flag)break,if(flag)printf("YES"),if(y==x)flag=1,i++,y=pow(2,i)
   );

5 commentaires

Puisqu'il utilise int s, ne serait-il pas préférable de les utiliser (et de sauter le cas spécial pour 0)?


@James: Ceci serait une conversion implicite. Je ne vois aucun mal. Mais pourquoi l'affaire spéciale devrait-elle être ignorée?


@James: Je ne trouve rien d'illégal dans mon code.J'ai suivi toutes les règles.


@Dirk: parce que (0 & -1) == 0. Le cas particulier n'est nécessaire que dans X-1 est illégal.


@James Curran: Vous avez mal compris le cas spécial. (0 &--1) == 0 est certainement vrai, mais depuis 0 est pas une puissance de deux, "vrai" ne doit pas être retourné dans ce cas. Ceci est vrai si vous utilisez des valeurs non signées ou signées (et x-1 avec un x == 0 est parfaitement légal).



8
votes

Je ne vais pas répondre directement, mais je remarquerai qu'une puissance de deux n'a qu'un seul bit, et lorsque vous soustrayez l'un d'un nombre, il efface le moindre bit significatif. C'est défini et définit tous les bits moins importants. En regardant l'un de ces faits, puis l'autre pourrait donner une idée de la manière de détecter la première condition d'une ligne.


2 commentaires

Voulez-vous dire il efface le bit le plus significatif qui est défini


@Cholthipaulttiopic: Non. Il efface le moindre le moins significatif qui est actuellement défini. Donc donné (par exemple) 0111000 , le bit le moins significatif actuellement défini est bit 3. Si nous soustrayons 1, le bit 3 sera effacé et les bits 0 à 2 seront définis (et tous les plus élevés Les bits restent inchangés), donnant 0110111 .



1
votes

Avec l'opérateur de la virgule, les expressions sont évaluées de gauche à droite, de sorte que votre `if (drapeau) printf (" oui ") ne sera jamais exécuté.

Je suis curieux de ce que le point de ceci est, comme (val! = 0) && ((Val & val-1) == 0) retourne non-zéro si une valeur est une valeur pouvoir de deux.


0 commentaires

5
votes

Personnellement, j'aime bien cette saveur:

bool isPow2 = ((x & ~(x-1))==x)? x : 0;


0 commentaires