Premier ou pas?

Soyez le premier à donner votre avis sur cette source.

Vue 4 653 fois - Téléchargée 816 fois

Description

Ce petit programme, qui est d'ailleurs mon premier vrai programme, est capable de dire si le nombre que l'on saisi est premier ou pas.
J'ai mis une limite de nombre pour ne pas que le calcul soit trop long et ralentisse l'ordinateur.
Il y a sûrement plein de choses inutiles dans le programme, mais c'est pour une compréhension visuelle de la chose, et aussi car j'ai voulu "explorer" quelques fonctionnalités du langage delphi.
J'ai même essayer de faire un raccourcis clavier via entrée.

Source / Exemple :


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Edit1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Var
  i,c:integer;
  z,e:string;
  b,a,g:extended;
begin
  g:=strtofloat(edit1.text);
  a:=sqrt(g);
  c:=round(a);
  e:='Merci de bien vouloir respecter les consignes';
  if g>2000000000
  then edit2.Text:=e
  else
    begin
    if g=0
    then edit2.Text:=e;
    if int(g/2)=g/2
    then
    edit2.text:='Il est pair, donc pas premier'
    else
      begin
      i:=1;
      for i:=i+2 to c do
        begin
        b:=g/i;
        if int(b)=g/i
        then
          begin
          z:='Il n''est pas premier et impair';
          edit2.Text:=z
          end
        else
          begin
          if edit2.text=z
          then edit2.Text:=z
          else edit2.Text:='Il est premier et différent de 2, il est donc aussi impair';
          end;
        end;
      if edit2.Text=z
      then edit2.Text:=z
      else edit2.Text:='Il est premier et différent de 2, il est donc aussi impair';
      if g=1
      then edit2.Text:='1 n''est pas un nombre premier, car il a un seul diviseur dans N: lui-même';
      end;
    if g=2
    then edit2.Text:='2 est premier et pair, c''est le seul nombre premier pair';
    if edit2.Text=z
    then form1.color:=clred
    else form1.color:=clgreen;
    if edit2.Text='Il est pair, donc pas premier'
    then form1.Color:=clred;
  end;
end;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  form1.Color:=clbtnface;
  edit2.Text:='Verdict';
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
Var
  i,c:integer;
  z,e:string;
  b,a,g:extended;
begin
  if key=#13
  then
  begin
    g:=strtofloat(edit1.text);
    a:=sqrt(g);
    c:=round(a);
    e:='Merci de bien vouloir respecter les consignes';
    if g>2000000000
    then edit2.Text:=e
    else
      begin
      if g=0
      then edit2.Text:=e;
      if int(g/2)=g/2
      then
      edit2.text:='Il est pair, donc pas premier'
      else
        begin
        i:=1;
        for i:=i+2 to c do
          begin
          b:=g/i;
          if int(b)=g/i
          then
            begin
            z:='Il n''est pas premier et impair';
            edit2.Text:=z
            end
          else
            begin
            if edit2.text=z
            then edit2.Text:=z
            else edit2.Text:='Il est premier et différent de 2, il est donc aussi impair';
            end;
          end;
        if edit2.Text=z
        then edit2.Text:=z
        else edit2.Text:='Il est premier et différent de 2, il est donc aussi impair';
        if g=1
        then edit2.Text:='1 n''est pas un nombre premier, car il a un seul diviseur dans N: lui-même';
        end;
      if g=2
      then edit2.Text:='2 est premier et pair, c''est le seul nombre premier pair';
      if edit2.Text=z
      then form1.color:=clred
      else form1.color:=clgreen;
      if edit2.Text='Il est pair, donc pas premier'
      then form1.Color:=clred;
    end;
  end;
end;

end.

Conclusion :


Je suis ouvert à toutes les critiques et conseils

Codes Sources

A voir également

Ajouter un commentaire Commentaires
blueperfect
Messages postés
234
Date d'inscription
mardi 13 novembre 2007
Statut
Membre
Dernière intervention
21 novembre 2013

5 janv. 2010 à 01:56
On peut également se lancer dans l'achat d'un MathLib quelconque....
Bacterius
Messages postés
3792
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
9
4 janv. 2010 à 23:41
Evidemment, on peut tenter d'implémenter son algorithme en assembleur pour tenter d'aller plus vite (ça permet, parfois, de gagner un temps variable, pouvant aller de rien du tout à une énorme amélioration). Cependant, comme l'assembleur est assez ... ah ... difficile à lire pour les non-initiés, on préfère toujours faire deux versions : une en Delphi, moins rapide mais lisible, et une en assembleur, rapide mais imbuvable.
Moi j'aime particulièrement les optimisations mathématiques, par exemple un modulo couteux qui se résume à deux opérations logiques et une addition ... quand le modulo est un nombre de Mersenne.
Si tu veux vraiment voir de l'assembleur en pleine action, cherche l'UnitGInt sur internet : c'est une très bonne librairie de grands nombres entièrement codée en assembleur, et je m'en sers quotidiennement ;)

Cordialement, Bacterius !
cmdmcmdm
Messages postés
4
Date d'inscription
jeudi 31 janvier 2008
Statut
Membre
Dernière intervention
4 janvier 2010

4 janv. 2010 à 22:51
C'est sûr que l'implémentation d'un code en assembleur est assez spécialisée et que la recherche de nombres premiers par les méthodes classiques est plus efficace que la recherche d'un diviseur ( cfr Wikipedia pour les méthodes ).
Maintenant je trouve assez fun de voir des gens qui se consacre à des écritures de code Assembleur et personnellement ce que je trouve extraordinaire avec ce type de code c'est de voir la rapidité des machines à notre disposition
Recherche de 0 à 10 millions sur un quart de processeur ( soit 4 secondes pour un code optimisé sur les 4 corps et 664579 nombres trouvés)
Heure début :
22:40:29
664579
Heure fin :
22:40:45

J'avais essayé à l'époque en basic puis en turbo pascal ( 100 fois plus rapide ) ce genre de programme de division (non assemblé) , je ne vous dis pas les nuits blanches de l'ordinateur de l'époque pour arriver à 1 million !

En ce qui concerne le "sérieur" c'est clair qu'un bon algorithme c'est d'abord la meilleure méthode mathématique et hardware et ensuite le bon code sur un bon compilateur. Mais je suis persuadé que dans certains programmes notamment graphique le code assembleur est utilisé, même indirectement, pour améliorer les performances. je ne sais pas, par contre, si il y en a beaucoup dans Windows.... au vu des performances ...

A+
Bacterius
Messages postés
3792
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
9
4 janv. 2010 à 13:12
Hmm super. Et que crois-tu que l'auteur de la source va y comprendre ?
De toute façon, ne nous leurrons pas. Aujourd'hui, ce code "rapide" ne tient pas la route pour une quelconque utilisation sérieuse. C'est pourquoi je proposais à Ludokk de se concocter ses implémentations de Miller-Rabin, Fermat, ou encore AKS (ou c'est plus dur, et alors ?), afin de toujours les avoir sous la main en cas de besoin :p

Cordialement, Bacterius !
cmdmcmdm
Messages postés
4
Date d'inscription
jeudi 31 janvier 2008
Statut
Membre
Dernière intervention
4 janvier 2010

4 janv. 2010 à 13:02
J'ai un code qui inclut de l'assembleur pour une recherche très rapide glané sur le net
Merci aux auteurs

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Memo1: TMemo;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure UDivMod(const Dividend, Divisor: LongWord; var Result, Remainder: LongWord); register;
asm
push ebx;
mov ebx,edx;
xor edx,edx;
div ebx;
mov ebx,Remainder;
mov [ecx],eax;
mov [ebx],edx;
pop ebx;
end;

function IsPrimeNumber(const Number: LongWord): boolean;
var DivisorA,
DivisorB,
Modulo,
DivisorsCount : LongWord;
begin
Result := false;
if Number < 2 then
exit;
DivisorA := 1;
DivisorB := Number;
Modulo := 0;
DivisorsCount := 0;
if DivisorA < DivisorB then
repeat
UDivMod(Number, DivisorA, DivisorB, Modulo);
if Modulo = 0 then
DivisorsCount := DivisorsCount + 2;
DivisorA := DivisorA + 1;
until (DivisorA >= DivisorB) or (DivisorsCount >= 3); Result :DivisorsCount 2;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
i,nb,max,min : integer;

begin
nb:=0;
form1.Memo1.Clear;
min := strtoint(form1.Edit2.Text);
max := strtoint(form1.Edit1.Text);
form1.Memo1.Lines.Add('Heure début :' ) ;
form1.Memo1.Lines.Add(timetostr(now)) ;

for i := min to max do
begin
//form1.Memo1.Lines.Add(inttostr(i)) ;
if IsPrimeNumber(i) then
begin
inc(nb);
// form1.Memo1.Lines.Add(inttostr(i))
end;

end;

form1.Memo1.Lines.Add(inttostr(nb)) ;
form1.Memo1.Lines.Add('Heure fin : ') ;
form1.Memo1.Lines.Add(timetostr(now)) ;
end;

end.
Afficher les 8 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.