MuPuF
Messages postés536Date d'inscriptionmercredi 27 avril 2005StatutMembreDernière intervention22 août 2008
-
20 juin 2005 à 09:38
rrk275
Messages postés540Date d'inscriptionvendredi 25 juin 2004StatutMembreDernière intervention 1 octobre 2007
-
10 nov. 2005 à 15:10
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
CoolMouse
Messages postés5Date d'inscriptionmercredi 16 février 2005StatutMembreDernière intervention10 novembre 2005 10 nov. 2005 à 02:22
Merci pour toutes ces explications, je vais étudier tout ça, et éventuellement mettre une mise à jour en place.
cs_Kirua
Messages postés3006Date d'inscriptiondimanche 14 avril 2002StatutMembreDernière intervention31 décembre 2008 18 oct. 2005 à 18:19
d'une manière générale, tu ne dois tester que la division par les nombres premiers inférieurs ou égaux à la racine carrée du nombre que tu testes. autrement dit: si tu génères, avec le crible d'eratosthène, les nombres premiers de 1 à 500 000 000 (c'est vite fait, le problème c'est la mémoire, si tu optimises bien ton algo ça roule), tu peux tester la primalité d'un nombre compris entre 500 000 000 et 250 000 000 000 000 000 en un temps proportionnel à la racine carrée du nombre testé: chouette :). le seul hic: il faut utiliser une classe de gestion des nombres très grands, et c'est plus lent.
si tu ne t'intéresses qu'aux naturels accessibles via un long long int (32 bits sur la plupart des machines), tu ne dois utiliser le crible que sur l'intervalle de 1 à sqrt(2^32) 2^16 65 536 (faut tjs connaître sa table de puissances de 2 :p), et ça c'est fait en moins d'une milliseconde, promi juré ^^.
rrk275
Messages postés540Date d'inscriptionvendredi 25 juin 2004StatutMembreDernière intervention 1 octobre 20072 17 oct. 2005 à 22:50
(j'ai oublié d'expliquer regarder bien il y a un code entre /** **/ c'était pour faire la comparaison)
rrk275
Messages postés540Date d'inscriptionvendredi 25 juin 2004StatutMembreDernière intervention 1 octobre 20072 17 oct. 2005 à 22:49
je pense qu'on pourrait faire p+=2 simple commodité permettant de tester que les pairs ...
a quoi sert le m ???
/**#include <cstdlib>
#include
#include <math.h>
using namespace std;
int main(int argc, char *argv[])
{
int i = 0, // Incrémenteur définissant le nombres de Premiers trouvés
c = 2, // Variable d'utilisation d'opération
m = 2, // Résultat de l'operation Modulo (%)
p = 10000001 ; // Incrémenteur définissant les nombres susceptibles d'être Premier
for (i = 3 ; i <= 2000000 ; i ++)
{
m = 2 ; // Initialisation des variables
p ++ ;
while ( c != p )
{
for (c = 2 ; p % c != 0 ; c ++);
if (c == p) printf("%d\n",p); // Affiche le nombre premier trouve
else p ++;
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
*/
#include <cstdlib>
#include
#include <math.h>
using namespace std;
int main(int argc, char *argv[])
{
int i = 0, // Incrémenteur définissant le nombres de Premiers trouvés
c = 2, // Variable d'utilisation d'opération
m, // Résultat de l'operation Modulo (%)
p = 10000001 ; // Incrémenteur définissant les nombres susceptibles d'être Premier
for (i = 3 ; i <= 2000000 ; i ++)
{
m = 2 ; // Initialisation des variables
p +=2 ;m=sqrt(p);
c=0;
while (c <m)
{
for (c = 2 ; p % c != 0 && c <= m; c ++);
if (c > m)printf("%d\n",p); // Affiche le nombre premier trouve
else {p +=2;m=sqrt(p);}
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
voici le code transformé m sert a stocker sqrt cela permet de ne pas le recaluler a chaque fois vous verrez je crois avoir (en reprenant les differents coms) multiplié par 10 la vitesse a petite valeur et par 10000 pour des valeurs plus grandes faites le test !! j'ai laissé la vielle version...
cs_petifa
Messages postés215Date d'inscriptiondimanche 20 février 2005StatutMembreDernière intervention10 mars 2014 5 juil. 2005 à 08:27
Un ptit truc sur les nombres premier et qui peut optimiser :
AU lieu de parcourir tous les nombres de 2 à p pour savoir s'il est premier, il s'uffit de parcourirs de 2 jusqu'à sqrt(p) (racine carrée de p)
A vrai dire si le nombres p est par exemple 200,
sqrt(200) = 14,142
Il s'uffit de chercher s'il est divisible par un nombre compris entre 2 et 14 !!! Au lieu de chercher entre 2 et 200.
Sur de très grand nombres, on voit netement la différence,
Donc dans ce code, il serait préférable de changer le test d'arrêt de la boucle while, du for et du if :
#include <math.h>
......
while ( c <= sqrt(p) )
{
for (c = 2 ; p % c != 0 && c <= sqrt(p) ; c ++);
....
rrk275
Messages postés540Date d'inscriptionvendredi 25 juin 2004StatutMembreDernière intervention 1 octobre 20072 30 juin 2005 à 13:08
En plus il suffit d'afficher a la fin tous ceux trouver ...
rrk275
Messages postés540Date d'inscriptionvendredi 25 juin 2004StatutMembreDernière intervention 1 octobre 20072 30 juin 2005 à 13:06
le mieux serait d'enregistrer les nombres premiers a chacun trouvé, et ne diviser que par eux
cela ferait gagner enormement de temps .... (pour des n depassant 10000)
Saros
Messages postés921Date d'inscriptionvendredi 20 décembre 2002StatutMembreDernière intervention23 septembre 2010 30 juin 2005 à 10:44
Oups, j'avais mal compris :)
Je pensais que "cela excluant les nombres négatifs" relevait de "qui possède exactement 2 diviseurs"
cs_Kirua
Messages postés3006Date d'inscriptiondimanche 14 avril 2002StatutMembreDernière intervention31 décembre 2008 30 juin 2005 à 00:14
ben c'est ce que j'ai dit ...
Saros
Messages postés921Date d'inscriptionvendredi 20 décembre 2002StatutMembreDernière intervention23 septembre 2010 29 juin 2005 à 19:49
Un naturel est toujours positif (N = Z+) :)
Sinon, -1 ayant exactement deux diviseurs (-1 et 1), il serait premier...
cs_Kirua
Messages postés3006Date d'inscriptiondimanche 14 avril 2002StatutMembreDernière intervention31 décembre 2008 29 juin 2005 à 11:05
* FREE KEVIN *
(ça c'est pour le clin d'oeil à tsutomu)
Sinon, la définition valable est: "un nombre premier est un naturel qui possède exactement deux diviseurs."
Ceci excluant 1 et les nombres négatifs.
tsutomu
Messages postés1Date d'inscriptiondimanche 19 novembre 2000StatutMembreDernière intervention29 juin 2005 29 juin 2005 à 10:06
Euh..Chaque nombre pour être premier devant etre divisible soit par 1 , soit par lui même, et n'est divisible que par 1...Donc il n'appartient pas aux nombres premiers. Du reste, 2 est le seul nombre premier pair.. Sisi cherche bien, il n'est divisilbe que par 1 ou lui même :)
cs_Kirua
Messages postés3006Date d'inscriptiondimanche 14 avril 2002StatutMembreDernière intervention31 décembre 2008 28 juin 2005 à 23:54
euh, non cali, c'est du sûr: 1 n'est pas premier, et la légende vient d'une mauvaise formulation de la définition de primalité.
et dans mon message précédent, je voulais dire 500 000 000 ;)
cali_line
Messages postés1Date d'inscriptionmardi 21 juin 2005StatutMembreDernière intervention28 juin 2005 28 juin 2005 à 17:41
Je suis dsl Saros mais d'après ma définition, 1 est un nombre premier.
ma définition : "x est un nombre premier s'il est divisible que par 1 ou par lui meme..."
mais en cherchant un peu j'ai trouvé aussi ta définition.
apparemment il existe plusiseurs écoles et une grosse dispute pour le cas de 2
cs_Kirua
Messages postés3006Date d'inscriptiondimanche 14 avril 2002StatutMembreDernière intervention31 décembre 2008 21 juin 2005 à 22:46
Tu devrais t'intéresser à l'algorithme (avec un i) de eratosthène, c'est vieux mais extraordinnaire ^^ tu les génères jusque 500 000 très facilement si tu prends la peine d'optimiser ton algo.
D1m3x
Messages postés402Date d'inscriptionsamedi 28 décembre 2002StatutMembreDernière intervention21 juillet 20051 21 juin 2005 à 17:06
Salut,
moi j'utiliserais aussi une fonction inline pour se genre d'appel car le compilateur peut directement exécuté cette petite ligne ... A moins que tu ne place uniquement le printf( ) dans le if( ), ainsi tu n'as pas besoin de passer par une fonction supplémentaire ...
Peace
Saros
Messages postés921Date d'inscriptionvendredi 20 décembre 2002StatutMembreDernière intervention23 septembre 2010 20 juin 2005 à 12:01
1 N'EST PAS un nombre premier
Définition d'un nombre premier : "entier naturel ayant strictement deux diviseurs"
1 n'a qu'un diviseur, donc non
Mais bon on a tous fait cette erreur au moins une fois :)
Pour affiche j'aurais mis une macro
#define AFFICHE(p) (printf("%d", (p)))
mais bon... c'est du détail...
MuPuF
Messages postés536Date d'inscriptionmercredi 27 avril 2005StatutMembreDernière intervention22 août 2008 20 juin 2005 à 09:38
Bon je dirais rien sur l'algorythme, disons que je me suis jamais intéréssé a ce genre de défi ...
Sinon un truc qui me plait pas c'est l'appel de la fonction affiche. En fait ça ralenti l'algorythme car ya l'appel de la fonction qui se fait pour une ligne ce qui est inutile. Met directement printf ("%d ", premier); au lieu de l'appel de fonction.
Sinon tu peux essayer de mettre inline void affiche (int premier) comme def de fonction, ça devrait faire la meme chose (c'est bien une bonne solution ici ?).
Pour l'interface graphique c'est tjs du console, mais de toute facon, pour ce genre d'algo te fais pas chier ;-) si on regarde il y a beaucoup de prog en mode console, meme si ils sont appellés par des progs win32.
Bon teste de faire ce que je t'ais dis, et good luck cool mouse
10 nov. 2005 à 15:10
#include <cstdlib>
#include
#include <math.h>
bool tab[50000000];
using namespace std;
int main(int argc, char *argv[])
{
int a;
for(int i=0;i<50000000;i++)
tab[i]=true;
system("pause");
for(int i=2;i<50000000;i++)
{
if(tab[i])
{
for(a=1;i*(a+1)<50000000;a+=1)tab[a*i]=false;
}
}
printf("fin\n");
system("pause");
return EXIT_SUCCESS;
}
10 nov. 2005 à 02:22
18 oct. 2005 à 18:19
si tu ne t'intéresses qu'aux naturels accessibles via un long long int (32 bits sur la plupart des machines), tu ne dois utiliser le crible que sur l'intervalle de 1 à sqrt(2^32) 2^16 65 536 (faut tjs connaître sa table de puissances de 2 :p), et ça c'est fait en moins d'une milliseconde, promi juré ^^.
17 oct. 2005 à 22:50
17 oct. 2005 à 22:49
a quoi sert le m ???
/**#include <cstdlib>
#include
#include <math.h>
using namespace std;
int main(int argc, char *argv[])
{
int i = 0, // Incrémenteur définissant le nombres de Premiers trouvés
c = 2, // Variable d'utilisation d'opération
m = 2, // Résultat de l'operation Modulo (%)
p = 10000001 ; // Incrémenteur définissant les nombres susceptibles d'être Premier
for (i = 3 ; i <= 2000000 ; i ++)
{
m = 2 ; // Initialisation des variables
p ++ ;
while ( c != p )
{
for (c = 2 ; p % c != 0 ; c ++);
if (c == p) printf("%d\n",p); // Affiche le nombre premier trouve
else p ++;
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
*/
#include <cstdlib>
#include
#include <math.h>
using namespace std;
int main(int argc, char *argv[])
{
int i = 0, // Incrémenteur définissant le nombres de Premiers trouvés
c = 2, // Variable d'utilisation d'opération
m, // Résultat de l'operation Modulo (%)
p = 10000001 ; // Incrémenteur définissant les nombres susceptibles d'être Premier
for (i = 3 ; i <= 2000000 ; i ++)
{
m = 2 ; // Initialisation des variables
p +=2 ;m=sqrt(p);
c=0;
while (c <m)
{
for (c = 2 ; p % c != 0 && c <= m; c ++);
if (c > m)printf("%d\n",p); // Affiche le nombre premier trouve
else {p +=2;m=sqrt(p);}
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
voici le code transformé m sert a stocker sqrt cela permet de ne pas le recaluler a chaque fois vous verrez je crois avoir (en reprenant les differents coms) multiplié par 10 la vitesse a petite valeur et par 10000 pour des valeurs plus grandes faites le test !! j'ai laissé la vielle version...
5 juil. 2005 à 08:27
AU lieu de parcourir tous les nombres de 2 à p pour savoir s'il est premier, il s'uffit de parcourirs de 2 jusqu'à sqrt(p) (racine carrée de p)
A vrai dire si le nombres p est par exemple 200,
sqrt(200) = 14,142
Il s'uffit de chercher s'il est divisible par un nombre compris entre 2 et 14 !!! Au lieu de chercher entre 2 et 200.
Sur de très grand nombres, on voit netement la différence,
Donc dans ce code, il serait préférable de changer le test d'arrêt de la boucle while, du for et du if :
#include <math.h>
......
while ( c <= sqrt(p) )
{
for (c = 2 ; p % c != 0 && c <= sqrt(p) ; c ++);
....
30 juin 2005 à 13:08
30 juin 2005 à 13:06
cela ferait gagner enormement de temps .... (pour des n depassant 10000)
30 juin 2005 à 10:44
Je pensais que "cela excluant les nombres négatifs" relevait de "qui possède exactement 2 diviseurs"
30 juin 2005 à 00:14
29 juin 2005 à 19:49
Sinon, -1 ayant exactement deux diviseurs (-1 et 1), il serait premier...
29 juin 2005 à 11:05
(ça c'est pour le clin d'oeil à tsutomu)
Sinon, la définition valable est: "un nombre premier est un naturel qui possède exactement deux diviseurs."
Ceci excluant 1 et les nombres négatifs.
29 juin 2005 à 10:06
28 juin 2005 à 23:54
et dans mon message précédent, je voulais dire 500 000 000 ;)
28 juin 2005 à 17:41
ma définition : "x est un nombre premier s'il est divisible que par 1 ou par lui meme..."
mais en cherchant un peu j'ai trouvé aussi ta définition.
apparemment il existe plusiseurs écoles et une grosse dispute pour le cas de 2
21 juin 2005 à 22:46
21 juin 2005 à 17:06
moi j'utiliserais aussi une fonction inline pour se genre d'appel car le compilateur peut directement exécuté cette petite ligne ... A moins que tu ne place uniquement le printf( ) dans le if( ), ainsi tu n'as pas besoin de passer par une fonction supplémentaire ...
Peace
20 juin 2005 à 12:01
Définition d'un nombre premier : "entier naturel ayant strictement deux diviseurs"
1 n'a qu'un diviseur, donc non
Mais bon on a tous fait cette erreur au moins une fois :)
Pour affiche j'aurais mis une macro
#define AFFICHE(p) (printf("%d", (p)))
mais bon... c'est du détail...
20 juin 2005 à 09:38
Sinon un truc qui me plait pas c'est l'appel de la fonction affiche. En fait ça ralenti l'algorythme car ya l'appel de la fonction qui se fait pour une ligne ce qui est inutile. Met directement printf ("%d ", premier); au lieu de l'appel de fonction.
Sinon tu peux essayer de mettre inline void affiche (int premier) comme def de fonction, ça devrait faire la meme chose (c'est bien une bonne solution ici ?).
Pour l'interface graphique c'est tjs du console, mais de toute facon, pour ce genre d'algo te fais pas chier ;-) si on regarde il y a beaucoup de prog en mode console, meme si ils sont appellés par des progs win32.
Bon teste de faire ce que je t'ais dis, et good luck cool mouse