Page 1 sur 6
Turbo nombres premiers
Publié : lun. 23/mai/2011 2:03
par DjPoke
Bonsoir,
Je viens de terminer un programme de calcul (très ?) rapide de nombres premiers, basé sur mes propres recherches.
Je voudrais savoir si quelqu'un pourrait le tester, pour y trouver une éventuelle faille, mais aussi pour savoir s'il existe des algorithmes aussi rapides.
Merci d'avance.
Voici le code :
Code : Tout sélectionner
OpenConsole()
Repeat
PrintN("Entrez un nombre a verifier :")
a$=Input()
nb.q=Val(a$)
Premier=1
tt.f=ElapsedMilliseconds()
i.q=2
j.q=3
While (j.q*j.q)<=nb.q
j.q=j.q+1
Wend
While i.q<j.q
If (nb.q % i.q)=0
Premier=0
j.q=nb.q/i.q
PrintN(Str(i.q)+" * "+Str(j.q))
EndIf
i.q=i.q+1
Wend
tt.f=(ElapsedMilliseconds()-tt.f)/1000.000
If Premier=1
PrintN("Ce nombre est PREMIER !")
Else
PrintN("Ce nombre n'est PAS PREMIER !")
EndIf
PrintN("Temps de verification : "+StrF(tt.f))
PrintN("")
PrintN("Voulez vous verifier un autre nombre ? (o/n)")
a$=Input()
If LCase(a$)<>"o"
CloseConsole()
End
EndIf
PrintN("")
ForEver
Re: Turbo nombres premiers
Publié : lun. 23/mai/2011 8:21
par Fig
Déja quand le nombre se finit par 0-5 ou un chiffre pair, il ne peut pas être premier... Or ton programme se lance quand même dans des calculs interminables
Tu peux aussi virer tout les nombre qui ne satisfont pas au petit théorème de Fermat, tu es sûr qu'ils ne sont pas premiers.
Sinon, pourquoi tu ne fais pas une racine carré arrondie au dessus pour ton premier while/wend ?
Voila, sinon c'ets vrai que c'est déja assez rapide.
(punaise on a plus de amileys, il se passe quoi là ??)
Re: Turbo nombres premiers
Publié : lun. 23/mai/2011 13:43
par zaphod
...
Re: Turbo nombres premiers
Publié : lun. 23/mai/2011 16:50
par graph100
attention la =)
Va pas dire que PB est lent !!
quand je compile 3 - 4 fois, je tombe entre 0.67 sec et 0.60 sec
mais j'ai modifié le code : tu utilises des type trop grand ! ça ralenti le truc alors que c'est pour stocker des booléens
Code : Tout sélectionner
; algo nat the great pour blitzmax
; port en pb by zaphod - 23/05/2011
; en blitzmax = 0.838 sec
; en pb = 1.42 sec
; pentium 4 - 3 Ghz
;
; modifier par graph100
; avec la modif : 0.67 sec
; core2duo 2.50Ghz
;
; >>>> Compiler sans le debuger
;
Define num.i = 15485864
num + 1
Define sqrnum.i = Sqr(num) + 1
Dim PrimeFlags.b(num)
Dim Primes.i(num)
Define tim.i,count.i
Define mill.i = ElapsedMilliseconds()
For x = 2 To sqrnum
If primeflags(x) = #False
Primes(count) = x
count + 1
tim = x
Repeat
tim + x
primeflags(tim) = #True
Until x + tim >= num
EndIf
Next
For y = sqrnum To num - 1
If primeflags(y) = #False
Primes(count) = y
count + 1
EndIf
Next
mill = ElapsedMilliseconds()-mill
MessageRequester("", StrF(mill / 1000.0) + " seconds " + Str(count) + " primes found!")
Re: Turbo nombres premiers
Publié : lun. 23/mai/2011 17:36
par DjPoke
Merci pour vos réponses.
En tout cas, cela m'a fait réaliser à quel point PB est plus rapide que les autres.
Re: Turbo nombres premiers
Publié : lun. 23/mai/2011 19:14
par Le Soldat Inconnu
De cette manière, c'est encore plus rapide
Et ça corrige un bug sur la dernière valeur qui n'était pas un nombre premier dans le précédent algo, essai en visualisant les valeurs avec Num = 2000 et tu verra que 2000 est considéré comme nombre premier ...
0.326s chez moi sur un I5 2.67 MHz, vive PB.
0.5s avec ton code
Code : Tout sélectionner
; algo nat the great pour blitzmax
; port en pb by zaphod - 23/05/2011
; en blitzmax = 0.838 sec
; en pb = 1.42 sec
; pentium 4 - 3 Ghz
;
; >>>> Compiler sans le debuger
;
Define num.i = 15485864
Define sqrnum.i = Sqr(num)+1
Dim PrimeFlags.b(num)
Dim Primes.i(num)
Define tim.i,count.i = 2
Define mill.i = ElapsedMilliseconds()
;
For x = 3 To sqrnum Step 2
If PrimeFlags(x) = #False
tim = x + x
Repeat
PrimeFlags(tim) = #True
tim + x
Until tim >= num
EndIf
Next
;Local count:Int
Primes(1) = 2
For x = 3 To num Step 2
If PrimeFlags(x) = #False
Primes(count) = x
count+1
Debug x
EndIf
Next
mill = ElapsedMilliseconds()-mill
;
MessageRequester("",StrF(mill/1000.0) +" seconds "+ Str(count)+" primes found!")
Re: Turbo nombres premiers
Publié : lun. 23/mai/2011 19:49
par graph100
en fait j'avais oublié de compter 2 dans l'algo
sinon le dernier nb premier était bon dans ma version
et sur mon pc, il n'y a pas de différence nette entre ton algo (@lsi) et le mien, faudrait que je teste avec un plus grand nombre.
Mais effectivement ça va plus vite !
teste avec la modif suivante ^^ :
Code : Tout sélectionner
; algo nat the great pour blitzmax
; port en pb by zaphod - 23/05/2011
; en blitzmax = 0.838 sec
; en pb = 1.42 sec
; pentium 4 - 3 Ghz
;
; >>>> Compiler sans le debuger
;
Define num.i = 15485864
Define sqrnum.i = Sqr(num)+1
Dim PrimeFlags.b(num)
Dim Primes.i(num)
Define tim.i,count.i = 2
Define mill.i = ElapsedMilliseconds()
;
For x = 3 To sqrnum Step 2
If PrimeFlags(x) = #False
Primes(count) = x
count+1
tim = x + x
Repeat
PrimeFlags(tim) = #True
tim + x
Until tim >= num
EndIf
Next
;Local count:Int
Primes(1) = 2
For y = x To num Step 2
If PrimeFlags(y) = #False
Primes(count) = y
count+1
EndIf
Next
mill = ElapsedMilliseconds()-mill
;
MessageRequester("",StrF(mill/1000.0) +" seconds "+ Str(count)+" primes found!")
Re: Turbo nombres premiers
Publié : lun. 23/mai/2011 20:04
par Le Soldat Inconnu
ça devrait être plus rapide mais je ne vois aucune différence. j'ai testé en mettant Num = 200000000
Re: Turbo nombres premiers
Publié : lun. 23/mai/2011 20:19
par graph100
bah, le gain doit être négligeable ! Pense-tu qu'on peut faire plus rapide en assembleur ??
>< je test l'extension de erix14, c'est juste énorme ><
http://www.purebasic.fr/french/viewtopi ... 8&start=75
Re: Turbo nombres premiers
Publié : lun. 23/mai/2011 21:05
par Starwolf20
Salut !!
Re: Turbo nombres premiers
Publié : jeu. 26/mai/2011 8:12
par zaphod
...
Re: Turbo nombres premiers
Publié : jeu. 26/mai/2011 14:12
par graph100
Ça dépend peut être des différents processeurs qui ne sont pas gérer pareil par les langages ?
Faudrait avoir le truc en blitzmax pour pouvoir comparer sur différents pc
Re: Turbo nombres premiers
Publié : jeu. 26/mai/2011 23:08
par Starwolf20
L'algo de Nat the great est tres elegant, compact et efficace.
A titre d'information et puisque on a parlé d'assembleur, j'ai tenté de decortiquer le code generé par PB.
Sans être un UBER specialiste, je l'ai trouvé tres bon.
Atitre d'exemple, voici ce que ca donne en optimisant une partie du code.
Nb : Activez l'assembleur en ligne dans les options du compilateur.
Code : Tout sélectionner
; algo nat the great pour blitzmax
; port en pb by zaphod - 23/05/2011
; en blitzmax = 0.838 sec
; en pb = 1.42 sec
; pentium 4 - 3 Ghz
;
; >>>> Compiler sans le debuger
;
Define num.i = 15485864
Define sqrnum.i = Sqr(num)+1
Dim PrimeFlags.b(num)
Dim Primes.i(num)
Define tim.i,count.i = 2
Define mill.i = ElapsedMilliseconds()
;
For x = 3 To sqrnum Step 2
If PrimeFlags(x) = #False
Primes(count) = x
count+1
tim = x + x
;-------------------------------------- Partie du code remplacé en assembleur
;;; Repeat;
;;; PrimeFlags(tim) = #True
;;; tim + x
;;; Until tim >= num
; Repeat
MOV ebx,dword [v_tim]
MOV ebp,dword [a_PrimeFlags]
Repeat5:
; PrimeFlags(tim) = #True
;MOV ebx,dword [v_tim] ; deplacé en dehors de la boucle
;MOV ebp,dword [a_PrimeFlags] ; deplacé en dehors de la boucle
MOV byte [ebp+ebx],1
; tim + x
;MOV ebx,dword [v_tim]
ADD ebx,dword [v_x]
;MOV dword [v_tim],ebx ; deplacé en dehors de la boucle
; Until tim >= num
;MOV ebx,dword [v_tim]
CMP ebx,dword [v_num]
JL l_repeat5
;_Until5:
MOV dword [v_tim],ebx
;--------------------------------------
EndIf
Next
;Local count:Int
Primes(1) = 2
For y = x To num Step 2
If PrimeFlags(y) = #False
Primes(count) = y
count+1
EndIf
Next
mill = ElapsedMilliseconds()-mill
;
MessageRequester("",StrF(mill/1000.0) +" seconds "+ Str(count)+" primes found!")
Re: Turbo nombres premiers
Publié : ven. 27/mai/2011 1:25
par graph100
bah 0.5 sec pour moi
ça va plus vite effectivement, chez LSI, ça doit dépoter vu qu'il faisait 0.3 sec avant
Re: Turbo nombres premiers
Publié : ven. 27/mai/2011 17:43
par Le Soldat Inconnu
entre 0.280 / 0.296