progammation premier nombre

progammation premier nombre - C - Programmation

Marsh Posté le 11-11-2012 à 14:38:19    

bonjour j'ai une fonction a crée pour ensuite la mettre dans un programme et je comprend absolument rien j'ai lu et relu je cour plusieurs fois voila l'énoncer: Aider moi SVP  
 
Ecrire une fonction qui reçoit en paramètre un nombre entier et qui retourne vrai si ce nombre est premier ou
faux sinon . (fonction: bool premier(int )
Rappel : un nombre entier est premier s'il n'a que 2 diviseurs distincts : 1 et lui même

Reply

Marsh Posté le 11-11-2012 à 14:38:19   

Reply

Marsh Posté le 11-11-2012 à 16:04:52    

Ben montres nous déjà le code que tu as commencé à écrire.
Et les idées que tu as sur la méthode a utiliser pour tester si un nombre est premier ou pas.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 11-11-2012 à 21:08:40    

En C je dirais que ça donnerait un truc comme ça :

Code :
  1. int premier(int nombreEntier){
  2.    int prem=1;  //est premier
  3.    for (int i=2;i<=nombreEntier-1;i++){
  4.       if ( (nombreEntier % i) == 0){       //si le reste de la division est 0
  5.          prem=0;    //alors le nombre n'est pas premier
  6.       }
  7.    }
  8.    return prem;
  9. }

Reply

Marsh Posté le 11-11-2012 à 21:27:02    

Code :
  1. Yep, sauf que tu peux un peu optimiser ça :
  2. bool premier(int nombreEntier)
  3. {
  4.      for (int i=2;i<nombreEntier;i++)
  5.      {
  6.           if ( (nombreEntier%i)==0)
  7.                return false;
  8.      }
  9.      return true;
  10. }


 
Dès qu'il va détecter qu'un reste est à 0, il renvoi directement false, la boucle s'arrête (pas besoin de vérifier les autres)
A la fin de la boucle, la fonction renvoi vrai (Ceci-dit, bool existe bien en C, non ? :D).


---------------
Perhaps you don't deserve to breathe
Reply

Marsh Posté le 11-11-2012 à 21:58:32    

il n'y a pas de bool en C mais pour le reste je valide (avec un while) :)

Message cité 2 fois
Message édité par alex7532 le 11-11-2012 à 21:59:03
Reply

Marsh Posté le 11-11-2012 à 22:21:39    

alex7532 a écrit :

il n'y a pas de bool en C mais pour le reste je valide (avec un while) :)


Bien sur que si, il suffit de faire  
#include <stdbool.h>
et de ne pas vivre avec un compilo de l'âge des cavernes.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 11-11-2012 à 23:02:37    

Note : Si vous voulez absolument optimiser, autant ne tester que les nombres impairs (et gérer le cas de 2 à part), cela économise la moitié du boulot :)

Reply

Marsh Posté le 11-11-2012 à 23:58:36    

Après, tu peux toujours faire ça :  

Code :
  1. #define true 1
  2. #define false 0
  3. char premier(int nombre)
  4. {
  5. ...
  6. }


 
Comme ça, la fonction n'est signée que sur un seul octet (sauf cas particulier, mais il me semble que toute les machines interpréterons un char comme un seul octet et un w_char comme 2 octets)


---------------
Perhaps you don't deserve to breathe
Reply

Marsh Posté le 12-11-2012 à 03:40:49    

Farian a écrit :

Note : Si vous voulez absolument optimiser, autant ne tester que les nombres impairs (et gérer le cas de 2 à part), cela économise la moitié du boulot :)


Et ne pas non plus chercher un diviseur plus grand que la racine carrée du nombre, bref un truc de ce genre:
 

Code :
  1. bool premier(int nombreEntier) {
  2.     if ((nombreEntier % 2) == 0)
  3.         return false;
  4.     else {
  5.         int i, root  = sqrt(nombreEntier);
  6.         for (i = 3; i <= root; i += 2) {
  7.             if ((nombreEntier % i) == 0)
  8.                 return false;
  9.         }
  10.         return true;
  11.     }
  12. }


A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 12-11-2012 à 03:46:05    

alex7532 a écrit :

il n'y a pas de bool en C mais pour le reste je valide (avec un while) :)


Noter que pour la declaration de i comme int dans la boucle
for (int i=2;i<nombreEntier;i++)
faut au moins être en C99 pour qu'un compilo l'accepte.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 12-11-2012 à 03:46:05   

Reply

Marsh Posté le 12-11-2012 à 08:06:06    

gilou a écrit :


Et ne pas non plus chercher un diviseur plus grand que la racine carrée du nombre, bref un truc de ce genre:
 

Code :
  1. bool premier(int nombreEntier) {
  2.     if ((nombreEntier % 2) == 0)
  3.         return false;
  4.     else {
  5.         int i, root  = sqrt(nombreEntier);
  6.         for (i = 3; i <= root; i += 2) {
  7.             if ((nombreEntier % i) == 0)
  8.                 return false;
  9.         }
  10.         return true;
  11.     }
  12. }


A+,


 
 
Votre code renvoie vrai pour la valeur 1, et faux pour la valeur 2, ce qui est manifestement erroné. De plus, les nombres négatifs sont mal gérés (surtout l'appel à sqrt :) )...
 
Ma proposition (je n'aime pas les accolades ouvrantes en début de ligne et les instructions sans accolades après un if/for/while ... et j'aime bien qu'une fonction non-void se termine par un return)
 

Code :
  1. bool premier(int nombreEntier)
  2. {
  3.     int i, root ;
  4.     if (nombreEntier <= 1)
  5.     {
  6.          return false;
  7.     }
  8.     if (nombreEntier == 2)
  9.     {
  10.          return true;
  11.     }
  12.     if ((nombreEntier % 2) == 0)
  13.     {
  14.         return false;
  15.     }
  16.     root = sqrt(nombreEntier);
  17.     for (i = 3; i <= root; i += 2)
  18.     {
  19.          if ((nombreEntier % i) == 0)
  20.         {
  21.                 return false;
  22.         }
  23.     }
  24.     return true;
  25. }

Message cité 1 fois
Message édité par Farian le 12-11-2012 à 08:07:39
Reply

Marsh Posté le 12-11-2012 à 11:17:58    

Ben 1 est premier, donc :
 
if (nombreEntier<=2)
 return true;
 
C'est juste que Gilou n'a pas traité le nombre 2, et comme 2%2 = 0 , ça renvoi faux :spamafote:


---------------
Perhaps you don't deserve to breathe
Reply

Marsh Posté le 12-11-2012 à 13:23:05    

Je ne peux pas vous laisser dire ça  :)

 

Que faites-vous de l'unicité de la décomposition en facteurs premiers, si 1 l'est ?

 

De plus, votre formulation du test renvoie vrai pour 0, -1, -2, ...


Message édité par Farian le 12-11-2012 à 13:42:38
Reply

Marsh Posté le 12-11-2012 à 13:24:28    

les nombres negatifs ne peuvent pas etre premier par definition

 

et 1 n'est pas premier :o

Message cité 1 fois
Message édité par Joel F le 12-11-2012 à 13:24:47
Reply

Marsh Posté le 12-11-2012 à 13:30:54    

Farian a écrit :


 
 
Votre code renvoie vrai pour la valeur 1, et faux pour la valeur 2, ce qui est manifestement erroné. De plus, les nombres négatifs sont mal gérés (surtout l'appel à sqrt :) )...
 
Ma proposition (je n'aime pas les accolades ouvrantes en début de ligne et les instructions sans accolades après un if/for/while ... et j'aime bien qu'une fonction non-void se termine par un return)
 

Code :
  1. bool premier(int nombreEntier)
  2. {
  3.     int i, root ;
  4.     if (nombreEntier <= 1)
  5.     {
  6.          return false;
  7.     }
  8.     if (nombreEntier == 2)
  9.     {
  10.          return true;
  11.     }
  12.     if ((nombreEntier % 2) == 0)
  13.     {
  14.         return false;
  15.     }
  16.     root = sqrt(nombreEntier);
  17.     for (i = 3; i <= root; i += 2)
  18.     {
  19.          if ((nombreEntier % i) == 0)
  20.         {
  21.                 return false;
  22.         }
  23.     }
  24.     return true;
  25. }


Citation :

bref un truc de ce genre:

J'ai pas prétendu que c'était la solution finale, mais qu'il pouvait s'en inspirer. A lui ensuite de l'adapter à son code, la c'était pour lui montrer qu'on pouvait diviser par 4 le nombre de tour de boucles. Mea culpa, j'aurais du préciser qu'il devait s'occuper à part des nombres précédent la borne inférieure de la boucle, mais ça me semblait évident.
On pouvait encore optimiser avec une table statique des nombres premiers de 1 à 30 ou 50 qui sont en général bien connus (c'est ainsi qu'on règle le cas de 0, 1, 2, 3, 5...) habituellement.
 
Quand à ne pas traiter les nombres négatifs, c'est tout à fait normal, car je ne sais pas quelle définition des nombres premiers est adoptée pour son exercice:

Citation :

Rappel : un nombre entier est premier s'il n'a que 2 diviseurs distincts : 1 et lui même


Avec une telle définition, il n'y a pas de nombre premiers, tout nombre entier étant divisible par 1, -1, lui même et son opposé.
Avec la définition un nombre entier naturel est premier s'il n'a que 2 diviseurs entiers naturels distincts : 1 et lui même, la on a une définition qui marche. Et si on considère les entiers relatifs, c'est une question de point de vue.
 
A+,


Message édité par gilou le 12-11-2012 à 13:35:59

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 12-11-2012 à 13:35:14    

Joel F a écrit :

les nombres negatifs ne peuvent pas etre premier par definition
 
et 1 n'est pas premier :o

ça dépend de ta définition, cf mon post précédent.
La notion de nombre premier n'est bien définie et n'a de sens que pour les entiers naturels. Ensuite quand on passe aux entiers relatifs, il y a deux manières de l'étendre (grosso modo n est premier comme entier relatif s'il l'est comme entier naturel ou bien n est premier comme entier relatif si |n| l'est comme entier naturel) et choisir l'une ou l'autre n'a pas grande importance.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 12-11-2012 à 13:46:21    

Citation :

Ma proposition (je n'aime pas les accolades ouvrantes en début de ligne et les instructions sans accolades après un if/for/while ... et j'aime bien qu'une fonction non-void se termine par un return)


- Pour les accolades, il y a eu plusieurs études montrant que le style que j'ai adopté générait moins d'erreurs de relecture. C'est pourquoi j'ai changé de style et adopté celui qui est le plus efficace.
- les instructions uniques sans accolades c'est une question de gout, je trouve cela plus lisible on veut clairement indiquer qu'une action et une seule doit être effectuée, ce qui est le cas avec un return.
- Je préfère que le compilateur puisse m'indiquer un return manquant dans le code, ce qu'il ne pourra faire s'il y a un return inutile final.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 12-11-2012 à 13:57:39    

Pour le premier point, je trouve personnellement que c'est moins lisible, mais c'est là-encore une affaire de goût !
 
Pour le troisième, je ne suggère pas de mettre un return "inutile" à la fin du code, d'ailleurs, dans mon exemple, le return final est utile. Disons que c'est un compromis entre la règle "pas de return dans le code de la fonction", que je trouve un peu lourde à gérer au final et le fait de ne pas en avoir à la fin. Et, sauf erreur de ma part, avec les options par défaut, g++ n'émet pas de warning pour un return manquant (ce que j'ai toujours trouvé assez incompréhensible). Comme je n'ai pas eu le courage de lire ce que disent les normes C/C++ sur ce sujet ... :)

Reply

Marsh Posté le 13-11-2012 à 14:57:20    

Tiens, au fait, pourquoi ne pas faire ça de manière fonctionnelle, en exploitant la tail-recursion...
 

Code :
  1. bool is_prime(int i, int j, int k) {
  2.     if (k > j) return true;
  3.     if (!(i % k)) return false;
  4.     return is_prime(i, j, k+2);
  5. }
  6. bool prime(int n) {
  7.     if (n < 2) return false; // On choisit l'option nombre négatif -> false
  8.     if (!(n%2)) return (n == 2);
  9.     return is_prime(n, sqrt(n), 3);
  10. }


 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 13-11-2012 à 15:19:15    

Le code est élégant, mais peut consommer pas mal de pile, pour de grandes valeurs de n !!
 
Le stack overflow nous guette !! :)


Message édité par Farian le 13-11-2012 à 15:19:59
Reply

Marsh Posté le 13-11-2012 à 15:42:17    

Justement avec ce type de code, ce n'est pas nécessairement le cas.
Un compilo qui sait gérer correctement ce type d'appel récursif ne va pas faire d'empilement, mais va ré-exploiter le même emplacement mémoire pour les passages de paramètre successifs.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 14-11-2012 à 17:22:25    

voire il va faire de derecursifiage.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed