Autor Beitrag
MrSaint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1033
Erhaltene Danke: 1

WinXP Pro SP2
Delphi 6 Prof.
BeitragVerfasst: Sa 27.11.04 09:19 
OT
Gausi hat folgendes geschrieben:
1 ist speziell, weil es im "Ring" der ganzen Zahlen das "neutrale Element" der Multiplikation ist, d.h. 1*x=x für alle x.
0 ist ebenfalls keine Primzahl, sondern das neutrale Element der Addition, d.h. x+0=0 für alle x.


*schüttel* das erinnert mich grad an Körperaxiome... igittigitt ;)

_________________
"people knew how to write small, efficient programs [...], a skill that has subsequently been lost"
Andrew S. Tanenbaum - Modern Operating Systems
ScorpionKing
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1150

Win XP

BeitragVerfasst: Sa 27.11.04 09:23 
Mal eine andere Sache!
Geht folgende Funktion nicht auch um Primzahlen auszurechnen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function prim(i: integer): boolean;
var i2:integer;
begin
i2 := i mod 2;
if i2 > 0 then
begin
result := true;
end;
end;

_________________
Aus dem Urlaub zurück!
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 27.11.04 09:27 
Noch ne Frage: Irgendwer hat gestern gesagt, dass wenn ich die Primzahlen gespeicher hab, muss ich nur noch durch die Primzahlen teilen. Wie mach ich das genau?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  while ((Teiler <= Wurzel) AND (Result)) do
  begin
    if Zahl mod StrToInt(PrimS.Strings[Teiler]) = 0 then
    begin
      Result := False;
      Break;
    end;
    inc(Teiler, 2);
  end;

Viel zu langsam und auch noch falsch.
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 27.11.04 09:34 
@ScorpionKing: Zeigt 1. falsche Zahlen an und 2. man braucht 23 Sekunden mehr (23 Sek zu 0,9 Sek) und 3. kommt das daher, weil wenn du z.B. die 15 hast:

15 mod 2 = 7 Rest 1

Der Rest ist höher als 0, aber 15 ist keine Primzahl.
Phantom1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 390



BeitragVerfasst: Sa 27.11.04 10:15 
So jetzt will ich auch ma:

also eure function braucht bei 0 bis 100000 etwa 100 ms.
meine Function braucht dafür nur etwa 65 ms.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function isPrim(Zahl: Cardinal): Boolean;
var Teiler, MaxTeiler: Cardinal;
begin
  if zahl<2 then begin
    Result:=False;
    Exit;
  end;

  Result:=True;
  if Zahl=2 then Exit;

  MaxTeiler:=Trunc(Sqrt(Zahl));

  for Teiler:=2 to MaxTeiler do
    if Zahl mod Teiler = 0 then begin
      Result:=False;
      Break;
    end;
end;


mfg
Johannes Maier
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 173

Win XP
D7 Prof
BeitragVerfasst: Sa 27.11.04 11:12 
Gausi hat folgendes geschrieben:
Kroni hat folgendes geschrieben:
ansonsten bemerke ich mal, dass 1 laut definition auch eine Primzahl ist (1 ist durch sich selber und eins teilbar)...sowie die Null auch....also mach dann einfach eine da, wo zahl=2 or zahl=3 steht...einfach if zahl<4 then....

Aus mathematischer Sicht ist das falsch. 1 ist keine Primzahl, sondern eine "Einheit". Also eine Zahl, die man mit einer anderen (ganzen) Zahl zu 1 multiplizieren kann. -1 ist auch eine Einheit. 1 ist speziell, weil es im "Ring" der ganzen Zahlen das "neutrale Element" der Multiplikation ist, d.h. 1*x=x für alle x.
0 ist ebenfalls keine Primzahl, sondern das neutrale Element der Addition, d.h. x+0=0 für alle x.
Und diese "besonderen Zahlen" sind aus der Definition der Primzahlen ausgenommen.

[genug kluggeschissen, viel Erfolg mit dem Programm]

Also meiner Meinung nach lautet die Definition einer Primzahl: Eine Zahl, die genau zwei Teiler hat. Und da sind auch 0 und 1 ausgenommen. Die bekannte Definition "Eine Zahl, die nur durch 1 und sich selbst teilbar ist" ist falsch ... ;)
Aber das mit der Einheit ist auch logisch, nur verstehe ich dann nicht, wieso du sagt: Aus der Definition der Primzahlen ausgenommen? In der richtigen Definition ist sie gar nicht drin ;)

_________________
MfG
Johannes ehem. jbmaier
Johannes Maier
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 173

Win XP
D7 Prof
BeitragVerfasst: Sa 27.11.04 11:17 
Phantom1 hat folgendes geschrieben:
So jetzt will ich auch ma:

also eure function braucht bei 0 bis 100000 etwa 100 ms.
meine Function braucht dafür nur etwa 65 ms.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function isPrim(Zahl: Cardinal): Boolean;
var Teiler, MaxTeiler: Cardinal;
begin
  if zahl<2 then begin
    Result:=False;
    Exit;
  end;

  Result:=True;
  if Zahl=2 then Exit;

  MaxTeiler:=Trunc(Sqrt(Zahl));

  for Teiler:=2 to MaxTeiler do
    if Zahl mod Teiler = 0 then begin
      Result:=False;
      Break;
    end;
end;


mfg


Hmm habe jetzt nichts zum Testen da, aber wäre es nicht vielleicht schneller, die for-Schleife so zu Schreiben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
for Teiler := 2 to MaxTeiler do begin
  if Zahl mod Teiler = 0 then begin
    Result := False;
    Break;
  end;
  Inc(Teiler);
end;

Das Inc frisst noch ein bisschen Zeit, aber vll. wird das dadurch aufgehoben, dass man nur noch halb so oft mod verwendet ....
Btw: Vll. ist deine Funktion einfach schneller, weil du Cardinal verwendest ^^

_________________
MfG
Johannes ehem. jbmaier
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 27.11.04 12:43 
Am Cardinal liegts net (ausprobiert), aber an was dann?

Und wie mach ich das hier schneller:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  while ((Teiler <= Wurzel) AND (Result)) do
  begin
    if Trunc(Zahl / StrToInt(PrimS.Strings[Teiler])) = 0 then
    begin
      Result := False;
      Break;
    end;
    inc(Teiler, 1);
  end;
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Sa 27.11.04 13:11 
Zitat:
Also meiner Meinung nach lautet die Definition einer Primzahl: Eine Zahl, die genau zwei Teiler hat. Und da sind auch 0 und 1 ausgenommen.

Geht auch nicht undnedingt. Wenn mich meine Erinnerung an Zahlentheorie nicht trügt, dann geht das so:
Eine Element (ine ganze Zahl) p heißt prim, wenn aus p=a*b folgt: a ist eine Einheit oder b ist eine Einheit.

Z.B. kann man in den ganzen Zahlen 5 nur so zerlegen: 5=1*5 oder 5=-1*-5. Und 1 und -1 sind Einheiten, also ist 5 eine Primzahl. 6 ist keine, denn 6=2*3, und weder 2 noch 3 sind Einheiten.

_________________
We are, we were and will not be.
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 27.11.04 13:50 
Hab mir mal die Unit BigIntegers runtergeladen. Jetzt kann ich größere Zahlen brechnen.

EDIT: Ach das ist ein scheiß. Mal schauen, ob ich so ne Unit selber hinbekomm.
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Sa 27.11.04 14:07 
GTA-Place hat folgendes geschrieben:
Jetzt kann ich größere Zahlen brechnen.

Auch auf die Gefahr hin, dass ich mit meinem Mathe-Gedöns auf die Nerven gehe: Wenn du größere Zahlen durchgehen willst, dann wird dein Test langsam aber sicher uneffizient. Für Int64 mag das naive Verfahren gut gehen, aber wenn man noch (weit) darüber hinaus möchte, wäre es evtl. sinnvoll, mit etwas feinerem als einem Hammer an die Sache ranzugehen.
Als Einstiegspunkt kann ich Suche bei Google "MILLER-RABIN" angeben. Steckt ne Menge Mathematik dahinter, aber es findet sich bestimmt auch irgendwo einfach nur das Verfahren, ohne das ganze drumherum zu beweisen.

_________________
We are, we were and will not be.
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Sa 27.11.04 14:30 
Suche in: Delphi-Forum, Delphi-Library DIE SUCHE NACH DEN BEIDEN liefert z.B. diesen Beitrag. :-)

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 27.11.04 15:17 
Application.ProcessMessages wird jetzt nur noch alle 10000 Zahlen aufgerufen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
if X = Step then
        begin
          Application.ProcessMessages;
          inc(Step, 10000);
        end;


1-1000000:
jedes Mal App.: 8,719 Sekunden
nur alle 10000 Zahlen, App.: 2,64 Sekunden
Kroni Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 720

Win 98, Win ME, Win2k, Win XP
D3 Pro
BeitragVerfasst: Sa 27.11.04 16:24 
na ja, ist das einzig fehlerhafte an meiner mathematik die Primzahldefiniton??*heulz*
wenn ihr mir das beweisen könnt, dass 1 und 0 nich dazugehört glaub ich euch das...dann werd ich das auch mal meinen Lehrern zeigen....
Das andere Verfahren will ich mir auch mal angucken....weil ja klar weiß ich, dass unser bisheriges Verfahren ends langsam ist....klar geht das schneller...ich hab auch schon so die Idee wie das gehen könnt mit dem Teilen durch Primzahlen, die kleiner als die Zahl sind....würd auch n Haufen Zeit sparen.
Aber für mich war nur der Reiz da, mal so etwas auf minimalster Zeit aufzubauen....
@GTA:
Wir können uns gerne noch zusammen was überlegen....kein Thema=) hast mich ja schon in ICQ geaddet
edit: bin bis heute abend weg, muss ncoh unsern Laptop reparieren und noch so einige andere Dinge erledigen
patrick
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1481

WIN2k, WIN XP
D6 Personal, D2005 PE
BeitragVerfasst: Sa 27.11.04 16:41 
ich kann zwar nicht gerade nicht mit eigenem code aufwarten (bin auf dem sprung)aber wenns um primzahlen geht sind diese seiten das richtige:
www.mersenne.org/source.htm
und hier kann man nochmal nen anderen pascal source für die primzahlenfindung downloaden:
www.codepedia.com/zone24/cat416/16883.htm

ob dieser schneller oder langsamer ist? keine ahung aber von der struktur her glaub ich er müste langsamer sein

_________________
Patrick
im zweifelsfall immer das richtige tun!!!
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 27.11.04 17:30 
Naja, ich hab das in nem recht alten Projekt mal folgendermaßen gemacht:

ausblenden volle Höhe PrimProj.dpr
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
Program PrimProj;

{$APPTYPE CONSOLE}

Uses
    SysUtils,
    Classes,
    Forms;

Function MkLang(Zahl, Ziffern: Integer): String;
Var
    Str: String;
    X: Integer;
Begin
    For X := 1 To Ziffern Do
        Str := Str + '0';
    Result := Copy(Str + IntToStr(Zahl), Length(IntToStr(Zahl)) + 1, Ziffern);
End;

Type
  TArrayInt64 = Array[0..0Of Int64;
  PArrayInt64 = ^TArrayInt64;
Var
  FS: TFileStream;
  Primzahlen: PArrayInt64;
  CurrNum, CurrPrimIdx, MaxPrim, MaxTest: Int64;
  IsPrim, DoTest: Boolean;
  TmpSqrt: Extended;
  Tmp: String;
  STime, ETime: TDateTime;
  PrimCount, PrimMemSize: Integer;

  MS, SS, MM, HH, DD: WORD;
Begin
  MaxPrim := 0;
  While MaxPrim = 0 Do
  Try
    WriteLn('Bis zu welcher Zahl wollen Sie die Primzahlen ermitteln???');
    ReadLn(MaxPrim);
  Except
    MaxPrim := 0;
    Continue;
  End;
  STime := Now;
  GetMem(Primzahlen, 65536);
  PrimMemSize := 65536;
  CurrNum := 2;
  Primzahlen[0] := CurrNum;
  PrimCount := 0;
  Inc(CurrNum);
  Try
    Try
      While CurrNum <= MaxPrim Do
      Begin
        TmpSqrt := CurrNum;
        TmpSqrt := Sqrt(TmpSqrt); //Maximaler Testfaktor
        MaxTest := Round(TmpSqrt);

        IsPrim := true; //Primzahl = ja
        CurrPrimIdx := 0//Aktuelle Position
        DoTest := CurrPrimIdx <= PrimCount; //Im Bereich???

        If DoTest Then //Wenn ja, ...
        Begin
          IsPrim := (TmpSqrt <> Trunc(TmpSqrt));
          DoTest := IsPrim And (Primzahlen[CurrPrimIdx] <= MaxTest);
        End;

        While DoTest Do
        Begin
          IsPrim := CurrNum Mod Primzahlen[CurrPrimIdx] <> 0;
          Inc(CurrPrimIdx); //Nächste Primzahl testen...
          DoTest := IsPrim And (CurrPrimIdx <= PrimCount); //Noch im Bereich???
          If DoTest Then //Wenn ja, ...
          Begin
            DoTest := Primzahlen[CurrPrimIdx] <= MaxTest;
          End;
        End;

        If IsPrim Then
        Begin
          If PrimCount shl 3 + 8 >= PrimMemSize Then
          Begin
            PrimMemSize := PrimMemSize Shl 1;
            ReallocMem(Primzahlen, PrimMemSize);
          End;
          Inc(PrimCount);
          Primzahlen[PrimCount] := CurrNum;
          If PrimCount And $FFF = 0 Then
            Write(IntToStr(CurrNum) + #9);
        End;
        Inc(CurrNum, 2);
      End;
      ETime := Now;
      WriteLn(#13#10);
      Write('Ermitteln der Primzahlen fertig');
      If STime <> ETime Then
      Begin
        WriteLn(': ' + IntToStr(Round((MaxPrim - 1) / ((ETime - STime)
          * 86400))) + ' geprüfte Zahlen pro Sekunde'#13#10);
        DecodeTime(STime, HH, MM, SS, MS);
        DecodeTime(ETime, DD, MM, SS, HH);
        DD := Trunc(ETime - STime);
        WriteLn('Startzeit: ' + DateTimeToStr(STime) + '.' + MkLang(MS,
          3));
        WriteLn('Endzeit:   ' + DateTimeToStr(ETime) + '.' + MkLang(HH,
          3));
        DecodeTime(ETime - STime, HH, MM, SS, MS);
        WriteLn('----------------------------------');
        WriteLn('Benötigt:  ' + Format('%10d %s.%s.%s.%s', [DD,
          MkLang(HH, 2), MkLang(MM, 2), MkLang(SS, 2), MkLang(MS,
            3)]));
      End
      Else
        WriteLn;
    Except
      On E: Exception Do
      Begin
        WriteLn('Fehler ' + E.ClassName + ': ' + E.Message);
      End;
    End;
  Finally
    WriteLn(#13#10,
      'Bitte warten!!!'#13#10'Die gesammelten Daten der Primzahlen werden gespeichert!!!');
    Try
      FS := TFileStream.Create(ChangeFileExt(Application.ExeName,
        '.prm'),
        fmCreate Or fmShareDenyWrite);
      Try
        FS.Size := 0;
        FS.Write(Primzahlen[0], (PrimCount + 1) * SizeOf(Int64));
        WriteLn('Es wurden ' + IntToStr(FS.Size Div SizeOf(Int64)) +
          ' Primzahlen gespeichert ...');
      Finally
                FS.Free;
            End;
        Except
            On E: Exception Do
                WriteLn('Fehler ' + E.ClassName + ': ' + E.Message);
        End;
        FreeMem(Primzahlen);
        Read(Tmp);
    End;
End.


Ich weiß nicht, ob's unter D3 läuft, müsste aber theoretisch, weil ich's ohne Dyn. Arrays hab. Die waren mir zu langsam :D Wer aber genau hinguckt, wird feststellen, dass hier noch einiges zu optimieren geht ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 27.11.04 17:32 
Wenn ich das richtig sehe, verwendest du eine Funktion um große Zahlen zu berechnen.
Kroni Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 720

Win 98, Win ME, Win2k, Win XP
D3 Pro
BeitragVerfasst: Sa 27.11.04 19:30 
wenn ich aus INT64 mal nen Integer mache, müsste das funktionieren....ja du arbeitest ja schön mit Zeigern usw...soweit cihd as gesehen hab....Array von 0 bis 0 Deklarieren, dann n bissl Speicherplatz reservieren und dann mitm Zeiger das in das Array speichern oder so ähnlich ;-)
So wurde mir das auch mal erklärt....
Ichgucks mir mal an....
Gruß, Kroni
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 27.11.04 20:19 
Wir müssten das Überprüfen mal nach dem Sieb des Eratosthenes probieren.
Wir schreiben alle Zahlen in ein Array und löschen alle Zahlen, die durch 2, 3, 5, 7, 11, 13, 17, 19 und 23 teilbar sind. Alle zahlen die übrigbleiben, sind Primzahlen.
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Sa 27.11.04 20:22 
GTA-Place hat folgendes geschrieben:
Wir müssten das Überprüfen mal nach dem Sieb des Eratosthenes probieren.
Wir schreiben alle Zahlen in ein Array und löschen alle Zahlen, die durch 2, 3, 5, 7, 11, 13, 17, 19 und 23 teilbar sind. Alle zahlen die übrigbleiben, sind Primzahlen.


Wenn du obige Zahlenreihe (.., 17, 19, 23, ...) nicht fortführst wirst du bald Zahlen entdecken, die das Sieb "übersieht" ;)

AXMD