Autor |
Beitrag |
MrSaint
      
Beiträge: 1033
Erhaltene Danke: 1
WinXP Pro SP2
Delphi 6 Prof.
|
Verfasst: 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
      
Beiträge: 1150
Win XP
|
Verfasst: Sa 27.11.04 09:23
Mal eine andere Sache!
Geht folgende Funktion nicht auch um Primzahlen auszurechnen:
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
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: 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?
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
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: 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
      
Beiträge: 390
|
Verfasst: 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.
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
      
Beiträge: 173
Win XP
D7 Prof
|
Verfasst: 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
      
Beiträge: 173
Win XP
D7 Prof
|
Verfasst: 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.
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:
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
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: Sa 27.11.04 12:43
Am Cardinal liegts net (ausprobiert), aber an was dann?
Und wie mach ich das hier schneller:
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
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: 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
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: 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
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: 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 "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.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Sa 27.11.04 14:30
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
GTA-Place
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: Sa 27.11.04 15:17
Application.ProcessMessages wird jetzt nur noch alle 10000 Zahlen aufgerufen:
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 
      
Beiträge: 720
Win 98, Win ME, Win2k, Win XP
D3 Pro
|
Verfasst: 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
      
Beiträge: 1481
WIN2k, WIN XP
D6 Personal, D2005 PE
|
Verfasst: 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
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 27.11.04 17:30
Naja, ich hab das in nem recht alten Projekt mal folgendermaßen gemacht:
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..0] Of 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); MaxTest := Round(TmpSqrt);
IsPrim := true; CurrPrimIdx := 0; DoTest := CurrPrimIdx <= PrimCount; If DoTest Then Begin IsPrim := (TmpSqrt <> Trunc(TmpSqrt)); DoTest := IsPrim And (Primzahlen[CurrPrimIdx] <= MaxTest); End;
While DoTest Do Begin IsPrim := CurrNum Mod Primzahlen[CurrPrimIdx] <> 0; Inc(CurrPrimIdx); DoTest := IsPrim And (CurrPrimIdx <= PrimCount); If DoTest Then 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  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
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: Sa 27.11.04 17:32
Wenn ich das richtig sehe, verwendest du eine Funktion um große Zahlen zu berechnen.
|
|
Kroni 
      
Beiträge: 720
Win 98, Win ME, Win2k, Win XP
D3 Pro
|
Verfasst: 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
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: 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
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: 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
|
|
|