Partage
  • Partager sur Facebook
  • Partager sur Twitter

Nombre de fois divisible par deux

19 novembre 2019 à 21:50:54

Bonjour,

Je suis un débutant dans la programmation et voici un programme que j’essaye d’écrire.En-gros je rentre un chiffre pair et  je compte le nombre de fois ce chiffre est divisible  par 2.mais le programme m'affiche 1 pour tous les numéros que je donne en entrée.

voici le code:

#include <stdio.h>
#include <stdlib.h>

int main() {
	
	
	int count = 0;
	int x;
	int n;

	printf("Entrer un chiffre pair\n");
	scanf("%d",&n);
	if ((n%2) == 0){

		do {
			x = n/2;
			count += 1;
		}
		while(x == 1);

	printf("%d\n",count);
	}
	else {
		printf("Entrer un nombre valide\n");
	}

return 0;

}


Ou est l'erreur?

Merci d'avance.

  • Partager sur Facebook
  • Partager sur Twitter
19 novembre 2019 à 23:01:42

Le problème est dans ton algo. (boucle do while).

Dans ta boucle x est toujours égal à n/2 quelque soit le nombre d'itération de la boucle. De plus, elle ne reboucle que si x est égal à 1.

  • Partager sur Facebook
  • Partager sur Twitter
19 novembre 2019 à 23:03:47

Si tu rentre 8,

n vaudra 8 et si tu fais n/2 ça fait 8/2=4 donc "x" vaudra 4. quand au compteur il a augmenté de 1 car 8 est pair.

Mais ton problème il est ici :

while(x == 1);
printf("%d\n",count);

Premièrement : ta boucle while est mal écrite, elle devrait ressembler à ça :

while (condition)

{

instructions

}

y a un lien ici : https://openclassrooms.com/fr/courses/19980-apprenez-a-programmer-en-c/14722-les-boucles

Donc oublie pas d'enlever le point-virgule qui est après le mot while() sur ton code.

Deuxiemement : la condition de ton while est fausse, "Tant que n==1 ça veut rien dire.

Regarde avec le résultat 4 qu'on a eu en entrant 8, bein ta condition va faire quoi en voyant ce 4 ?

Corrige ton code et réfléchit patiemment à ce que tu veux faire et à ce que doit faire ta boucle.

-
Edité par BozoUntel 19 novembre 2019 à 23:05:48

  • Partager sur Facebook
  • Partager sur Twitter
Abou
20 novembre 2019 à 9:30:41

Salut,

Un nombre en base X est divisible autant de fois par sa base qu'il y a de digits significatifs moins 1 ou de l'index du digit de poids le plus elevé.

La division d'un nombre par sa base revient à faire un décalage des digits vers la droite(d123/d10 = d12 ; b101 / d2 = b10; 0xABC /d16 = 0xAB), on peut donc diviser tant qu'il y a au moins 2 digits (significatifs).

Donc en binaire, l'index du bit vrai de poids le plus fort donne le nombre de division par 2, ce qui tombe bien puisque les nombres sont stockés en binaire dans la mémoire.

b10 -> 1 fois

b11-> 1 fois aussi

b1110010101010 -> 12 fois

Bonne continuation.

  • Partager sur Facebook
  • Partager sur Twitter

Bonhomme !! | Jeu de plateforme : Prototype.

20 novembre 2019 à 19:43:23

rouloude a écrit:

Le problème est dans ton algo. (boucle do while).

Dans ta boucle x est toujours égal à n/2 quelque soit le nombre d'itération de la boucle. De plus, elle ne reboucle que si x est égal à 1.


oui j'ai compris ! la solution est :

	if (((n%2) == 0) && (n != 1) && (n !=0)){

		do {
			x = n/2;
			n = x;
			count += 1;
		}
		while(x != 1);



Je pense que tu seras d'accord avec moi.

En tout cas j'ai compris.

Merci beaucoup heureusement qu'il y a des gens comme vous qui consacre du temps pour lire et répondre pour aider les gens en difficultés.Continuez comme ça.

edgarjacobs j'ai modifié la condition if pour toi.

drxj'ai pas compris ce que tu veux dire.



-
Edité par LowBudgetStudios 20 novembre 2019 à 20:12:07

  • Partager sur Facebook
  • Partager sur Twitter
20 novembre 2019 à 20:01:43

Hello,

Hélas, ta solution ne fonctionne pas: quelle va être la réponse si n vaut 0 ou 1 ?

-
Edité par edgarjacobs 21 novembre 2019 à 17:24:47

  • Partager sur Facebook
  • Partager sur Twitter
20 novembre 2019 à 20:03:22

BozoUntel a écrit:

Si tu rentre 8,

n vaudra 8 et si tu fais n/2 ça fait 8/2=4 donc "x" vaudra 4. quand au compteur il a augmenté de 1 car 8 est pair.

Mais ton problème il est ici :

while(x == 1);
printf("%d\n",count);

Premièrement : ta boucle while est mal écrite, elle devrait ressembler à ça :

while (condition)

{

instructions

}

y a un lien ici : https://openclassrooms.com/fr/courses/19980-apprenez-a-programmer-en-c/14722-les-boucles

Donc oublie pas d'enlever le point-virgule qui est après le mot while() sur ton code.

Deuxiemement : la condition de ton while est fausse, "Tant que n==1 ça veut rien dire.

Regarde avec le résultat 4 qu'on a eu en entrant 8, bein ta condition va faire quoi en voyant ce 4 ?

Corrige ton code et réfléchit patiemment à ce que tu veux faire et à ce que doit faire ta boucle.

-
Edité par BozoUntel il y a environ 20 heures

Tu as raison pour x==1 (tu t'es trompé t'as mis n==1 change pour pas qu'il y ait pas d'ambiguïté pour les gens qui consulteront ce topic ) :

La boucle s'exécutera au moins une fois comme c'est un do-while.

puis arrivé au condition de while comme x est différent de 1 condition devient fausse donc on sort de boucle.la solution est de mettre un !=

comme j'ai mis et de re attribuer x au n(voir ma reponse à rouloude).

Mais en ce qui concerne la boucle while il y en a deux while et do-while.

et do-while s'ecrit de cette façon:

do{
     instructions;
   }
   while(condtion);

en-gros on exécute les instructions tant-que la condition devient fausse.

En tout cas merci pour ta reponse



  • Partager sur Facebook
  • Partager sur Twitter
21 novembre 2019 à 10:39:07

Salut.

En base 10, celle que l'on utilise tous les jours, diviser par 10 revient à décaler les chiffres vers la droite et le chiffre le plus à droite disparait (pour les entiers):

12533 / 10 = 1253

1235/10 = 123

123/10 = 12

12/10 = 1

1/10 -> non (pas un entier en tout cas).

Donc en base 10 un nombre de X chiffres est divisible par 10 (X-1) fois.

Dans un nombre, le "poids" d'un chiffre (on dit digit parce que ce ne sont pas toujours des chiffres) est défini par sa position dans la valeur.

Les poids vont de 0 à ... en partant de la droite, il attribue une valeur au digit dans le nombre par sa valeur * base^poids.

pour 123, on a bien 123 = 3*10^0 + 2*10^1 + 1*10^2.

En binaire 101 vaut 1*2^0 + 0*2^1 + 1*2^2.

Donc le digit significatif de poids le plus fort d'un nombre donne le nombre de division possible par sa base.

52327663 -> le poids de 5 est 7 (5*10^7), donc ce nombre est divisible 7 fois par 10

b11001101101 -> le poids du 1 de gauche est de 10 (1*2^10) donc ce nombre est divisible 10 fois par 2.

Un nombre est stocké en binaire en mémoire, il suffit donc de trouver le bit de poids le plus fort.

Attention aux nombre négatifs qui sont stockés en complément, il faut donc utiliser une valeur positive :

int numOfDivByTwo(int value)
{
    if (value<0)
        value = -value; //utiliser un nombre positif si value est négatif pour supprimer le complément.
    //départ de i sur : nombre de bit dans un int moins 1.
    for(int i = sizeof(value) * CHAR_BIT - 1; i>=0; i--)
    {//on va "scanner le nombre de gauche à droite
        
        if(value & (1<<i))//si on trouve un bit à 1
            return i;//on retourne le poids auquel on l'a trouvé
    }
    return 0;//par défaut le nombre n'est pas divisible par 2
}

Bonne continuation.

-
Edité par drx 21 novembre 2019 à 10:41:14

  • Partager sur Facebook
  • Partager sur Twitter

Bonhomme !! | Jeu de plateforme : Prototype.

26 novembre 2019 à 5:19:41

@drx:
C'est la méthode la plus rapide.
Cependant, on évite de mentionner les opérateurs de décalage ou logiqques dans les cours.
On n'est pas nécessairement supposé connaître le format des nombres dans la mémoire.
C'est pourquoi les gens utilisent les opérateurs * / ou %
  • Partager sur Facebook
  • Partager sur Twitter

Le Tout est souvent plus grand que la somme de ses parties.

9 avril 2022 à 13:27:12 - Message modéré pour le motif suivant : Merci d'utiliser le bouton code du forum pour insérer votre code


9 avril 2022 à 14:53:29

Bonjour,

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter

Pas d'aide concernant le code par MP, le forum est là pour ça :)