Autor Beitrag
Fiete
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 601
Erhaltene Danke: 339

W7
Delphi 6 pro
BeitragVerfasst: Mi 21.03.12 17:15 
Das Programm berechnet die Periode von Dezimalbrüchen.
Zähler und Nenner werden eingegebe, als Ergenis erhält man die Periodenlänge.
z.B.
1:109=0,009174311926605504587155963302752293577981651376146788990825688073394495412844036697247706422018348623853211
Periodenlänge = 108
Periode von der 1-ten bis zur 108-ten Stelle

Zähler und Nenner können maximal acht Ziffern lang sein!
Gruß Fiete
Einloggen, um Attachments anzusehen!
_________________
Fietes Gesetz: use your brain (THINK)
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mi 21.03.12 19:20 
Hallo,

wau, dass ist schon fast 10 Jahre her, dass ich das mal probiert habe:
www.webplain.de/fore...1,3861,3861#msg-3861
Aber das beschriebene Verfahren aus
www.mathematik-online.de/F103.htm
habe ich nicht probiert.
Irgendwelche KGV bilden
Dein Beispiel mit dem Nenner 1094 und dessen Teiler 2 und 547
Zitat:
Aufgrund des Satzes von Joseph Lagrange wissen wir außerdem, dass die Ordnung eines Elementes einer Gruppe G die Ordnung von G teilt. Folglich ist m ein Teiler der Gruppenordnung 22 von Z*23, und damit gilt: m = 1, 2, 11 oder 22.

Hier ist die Gruppenordnung von Teiler1 = 2 -1= 1 mit dem Teiler: 1
und die von Teiler2 = 547 -1=> 546 mit den Teilern: 1,2,3,91
Die Periode kann maximal so lang wie der größte Teiler sein, dass beschränkt schon einmal das KGV, aber warum hier nun die 91 zum tragen kommt??
ganz unten www.mathematik-online.de/F103.htm
Zitat:
Wegen der leicht zu überprüfenden Aussagen: 10 1 ≠ 1, 1 02 ≠ 1 und 10 11 ≠ 1 muss m = 22 sein. Analog berechnet man für 3 ∈ Z*7 die Ordnung k = 6.

Bahnhof! Ich will zu meiner Gruppe ;-)

Gruß Horst
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Do 22.03.12 23:58 
Hallo,

@Fiete:
ich habe mir das Programm nochmals zu Gemüte geführt.
Du hast ja auch, wie ich damals, einfach in einem Feld der Größe Divisor-1 gemerkt, wann ein Rest wieder aufgetreten ist.
Jetzt ist mir die Idee gekommen, mal festzustellen, wann die Periode spätestens beginnt.
Mein Gedanke war nun der, dass wenn der Rest wieder auftaucht, sich die Abfolge der Reste ja komplett wiederholt.
Wenn ich mir den 100.sten Rest merke und dann einfach nur teste, wann dieser wieder auftaucht, habe ich die Periode auch bestimmt.
Ergo, wenn ich weiß, das bei der Zahl x die Periode spätestens nach y Berechnungen beginnt, merke ich mir stur den Rest der y.ten Berechnung und rechne weiter bis dieser Rest wieder auftaucht.
Damit brauche ich das ganze Feld nicht mehr :-)

Das Schönste kommt aber noch:
Ich kann vorher bestimmen, wann spätestens die Periode beginnt.
Die Folge ist ganz simpel
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
Zahl   max. Periodenbeginn nach y Stellen
3      1
6      2
12     3
...
x2     +1
..     ..
24576   14
24576x2  14+1
...

y = ln(Zahl/3)/ln(2)+1
Für Divisor = High(Longint) ist y = 30.
Also brauche ich mir nur den Rest der 30.ten Berechnung merken und solange weiterrechnen, bis dieser Rest wieder auftaucht, dass ist gegenüber dem abspeichern von 2 Milliarden Zahlen schon ein kleiner Gewinn.
Für die richtige Ausgabe muss ich mir aber doch die ersten 30 Berechungen speichern und mit den letzten 30 abgleichen.
Mal schauen, ob ich dies in ein Programm packe.

Gruß Horst
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Fr 30.03.12 06:18 
Hallo,

Arndt Brünner hat es wesentlich besser erklärt.Insbesondere die Euler Phi-Funktion.
www.arndt-bruenner.d...s/periodenlaenge.htm
Wozu das Ganze?
Bei mir verklemmmte sich Fiete's Version unter Linux mit wine.
Das lag wahrscheinlich mehr an der Speicherverwaltung bei Stringverlängerung.
Zeile := Zeile+Ziffer;
Ausserdem hat es mich nun gestört, dieses riesige und letztlich unnütze Restfeld zu benutzen.

Gruß Horst
Fiete Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 601
Erhaltene Danke: 339

W7
Delphi 6 pro
BeitragVerfasst: Fr 30.03.12 19:23 
Moin Horst_H,
mit meinem Programm wollte ich nicht nur die Periodenlänge sondern auch die Periode explizit errechnen.
Meine erste Version arbeitet mit der Phi-Funktion:
ausblenden volle Höhe Delphi-Quelltext
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:
{$R+,Q+}
 procedure TPeriode.Potenziere(Basis,Exponent,Modul:Int64;Var Ergebnis:Int64);
  begin
   Ergebnis:=1;
   While Exponent>0 DO
    begin
     if Exponent mod 2>0 then Ergebnis:=Ergebnis*Basis mod Modul;
     Basis:=Basis*Basis mod Modul;
     Exponent:=Exponent div 2
    end
  end;

 procedure TPeriode.RechneClick(Sender: TObject);
  const Max=447;
        Prim:Array[1..Max]of Integer=(
             235711131719232931374143475359,
             6167717379838997101103107109113127131,
             137139149151157163167173179181191193197,
             199211223227229233239241251257263269271,
             277281283293307311313317331337347349353,
             359367373379383,389397401409419421431433,
             439443449457461463467479487491499503509,
             521523541547557563569571577587593599601,
             607613617619631641643647653659661673677,
             683691701709719727733739743751757761769,
             773787797809811821823827829839853857859,
             863877881883887907911919929937941947953,
             967971977983991997100910131019102110311033,
             10391049105110611063106910871091109310971103,
             11091117112311291151115311631171118111871193,
             12011213121712231229123112371249125912771279,
             12831289129112971301130313071319132113271361,
             13671373138113991409142314271429143314391447,
             14511453145914711481148314871489149314991511,
             15231531154315491553155915671571157915831597,
             16011607160916131619162116271637165716631667,
             16691693169716991709172117231733174117471753,
             17591777178317871789180118111823183118471861,
             18671871187318771879188919011907191319311933,
             19491951197319791987199319971999200320112017,
             20272029203920532063206920812083208720892099,
             21112113212921312137214121432153216121792203,
             22072213222122372239224322512267226922732281,
             22872293229723092311233323392341234723512357,
             23712377238123832389239323992411241724232437,
             24412447245924672473247725032521253125392543,
             25492551255725792591259326092617262126332647,
             26572659266326712677268326872689269326992707,
             27112713271927292731274127492753276727772789,
             27912797280128032819283328372843285128572861,
             28792887289729032909291729272939295329572963,
             29692971299930013011301930233037304130493061,
             306730793083308931093119312131373163);

  var K,Nenner,PFIndex,PrimIndex,TeilerIndex,PhiVonNenner,Vergleich,
      Zwei,Fuenf,Nachkommastellen,Periode:Integer;
      Rest:Int64;
      PrimFaktorListe,TeilerListe:Array of Integer;
      Zeile:String;
      Rein:Boolean;
  begin
   if EditNenner.Text='' then
    begin
     MessageDlg('Der Nenner ist undefiniert!',mtError,[mbOk],0);
     Exit
    end;
   Nenner:=StrToInt(EditNenner.Text);
   PFIndex:=0;PrimIndex:=1;
   Ausgabe.Clear;
   repeat
    if Nenner mod Prim[PrimIndex]=0 then
     begin
      Nenner:=Nenner div Prim[PrimIndex];
      inc(PFIndex);
      SetLength(PrimFaktorListe,PFIndex);
      PrimFaktorListe[PFIndex-1]:=Prim[PrimIndex];
     end
    else inc(PrimIndex);
   until (Nenner=1or (PrimIndex>Max);
   if PrimIndex>Max then
    begin
     inc(PFIndex);
     SetLength(PrimFaktorListe,PFIndex);
     PrimFaktorListe[PFIndex-1]:=Nenner;
    end;
   Zeile:='';
   for K:=0 to PFIndex-1 do
    Zeile:=Zeile+Format('%6d',[PrimFaktorListe[K]]);
   Ausgabe.Lines.Add('Primfaktoren:'+Zeile);
   if (PrimFaktorListe[PFIndex-1]=2or (PrimFaktorListe[PFIndex-1]=5then
    begin // abbrechender Dezimalbruch
     Zwei:=0;Fuenf:=0;
     for K:=0 to PFIndex-1 do
      if PrimFaktorListe[K]=2 then inc(Zwei) else inc(Fuenf);
     if Zwei>Fuenf then Nachkommastellen:=Zwei else Nachkommastellen:=Fuenf;
     LabelErg.Caption:='abbrechender Dezimalbruch mit '+
                       IntToStr(Nachkommastellen)+' Nachkommastellen';
    end
   else
    begin
     PhiVonNenner:=1;Vergleich:=0;Nenner:=1;Rein:=True;
     for K:=0 to PFIndex-1 do
      if (PrimFaktorListe[K]<>2and (PrimFaktorListe[K]<>5then
       begin
        Nenner:=Nenner*PrimFaktorListe[K];
        if Vergleich=PrimFaktorListe[K] then
         PhiVonNenner:=PhiVonNenner*PrimFaktorListe[K]
        else PhiVonNenner:=PhiVonNenner*(PrimFaktorListe[K]-1);
        Vergleich:=PrimFaktorListe[K];
       end
      else Rein:=False;
     Zeile:='Phi('+IntToStr(Nenner)+')='+IntToStr(PhiVonNenner);
     Ausgabe.Lines.Add(Zeile);
     TeilerIndex:=1;
     SetLength(TeilerListe,TeilerIndex);
     TeilerListe[TeilerIndex-1]:=1;
     for K:=2 to PhiVonNenner div 2 do
      if PhiVonNenner mod K=0 then
       begin
        inc(TeilerIndex);
        SetLength(TeilerListe,TeilerIndex);
        TeilerListe[TeilerIndex-1]:=K;
       end;
     inc(TeilerIndex);
     SetLength(TeilerListe,TeilerIndex);
     TeilerListe[TeilerIndex-1]:=PhiVonNenner;
     Zeile:='';
     for K:=0 to TeilerIndex-1 do
      Zeile:=Zeile+Format('%7d',[TeilerListe[K]]);
     Ausgabe.Lines.Add('Teiler:'+Zeile);
     for K:=0 to TeilerIndex-1 do
      begin
       Potenziere(10,TeilerListe[K],Nenner,Rest);
       if Rest=1 then
        begin
         Periode:=TeilerListe[K];
         Break;
        end;
      end;
     if Rein then LabelErg.Caption:='reinperiodischer Dezimalbruch mit '
     else LabelErg.Caption:='gemischtperiodischer Dezimalbruch mit ';
     LabelErg.Caption:=LabelErg.Caption+'der Periodenlänge '+IntToStr(Periode);
    end;
  end;

Das vollständige Programm ist im Anhang
Gruß Fiete
Einloggen, um Attachments anzusehen!
_________________
Fietes Gesetz: use your brain (THINK)
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mi 04.04.12 12:48 
Hallo,

ich habe es mal in Freepascal für die Konsole komponiert und beides zusammengefügt.
Statt um die 67 Sekunden, mit Ausgabe, für 99999989 mit 99999988 Stellen dauert es etwa 2 Sekunden, ohne Ausgabe , dadurch, dass die Stringlänge zuvor festliegt.

Gruß Horst
Einloggen, um Attachments anzusehen!
Lelf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: Mi 04.04.12 19:49 
Vor Jahren habe ich auch einmal ein solches Programm entwickelt. Hier in Kürze, was noch hängen geblieben ist:

Es sei Bruch = 1 / Nenner
- zunächst werden die vorhandenen Faktoren 2 und 5 vom Nenner entfernt (Dezimal-System).
- man erhält eine Zahl N = p1*p2*...*pn. (Primzahlzerlegung).
- dann gilt:

- Periodenlänge = kleinste Zahl r für die gilt: 10^r == 1(mod N)
- für r = Phi(N) = (p1-1)*(p2-1)*...*(pn-1)


1.Beispiel: Nenner = 1094 = 2*547 | /2 (2 und 5, falls vorhanden entfernen)
N = 547
Phi(N) = 546 = 2*3*7*13 = r


10^r mod N == 1 mod N

10^546 mod 547 == 1 | 546 : 2 = 273

10^273 mod 547 == 1 | 273 : 3 = 91

10^91 mod 547 == 1 | 91 : 7 = 13

10^13 mod 547 == 544


also ist 91 die Periodenlänge von 1094



2.Beispiel:

Nenner = 1.393.125 = 3 * (5^4) * 743 | /625 (2 und 5, falls vorhanden entfernen)
N = 2229 = 3 * 743
Phi(N) = 1484 = 2 * 742 = (2^2) * 7 * 53 = r

10^r mod N == 1 mod N
10^1484 mod 2229 == 1 | 1484 : 2 = 742
10^ 742 mod 2229 == 1 | 742 : 7 = 106
10^ 106 mod 2229 == 592

also ist 742 die PeriodenLänge von 1.393.125
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mi 04.04.12 20:34 
Hallo,

genau so, wie es Fiete in seinem zweiten geposteten Programm gemacht hat.
Ich habe es nur kompbinert weil 99999989 irgendetwas um 800 Mb unterweges belete und bei 631 stehen blieb.Das schaffte mein Linux Notebook mit 1 Gbyte Ram unter wine nicht ohne auslagern, was mir wie ein hängenbleiben vorkam.

Gruß Horst
Lelf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: Fr 06.04.12 16:36 
@ Horst_H

Deine Idee, festzustellen, wann eine Periode spätestens beginnt, ist zwar richtig, aber nicht ganz zu Ende gedacht bzw. unklar formuliert. Das, was Du vermutlich meinst, nennt man: "Vorziffern eines gemischt-periodischer Dezimalbruchs" oder "reiner Teil" = Anzahl der Vorziffern, (daran anschließend die Anzahl der Ziffern des "periodischen Teils" = Periodenlänge.)


=============================================================================
Anzahl der Vorziffern = max(Exponent von 2, Exponent von 5) im Dezimal-System
=============================================================================


Beispiele (Bruch = 1 / Nenner):

Nenner \\ Primzahlzerlegung \\ Vorziffern
3 \\ 3 \\ 0
6 \\ 2 * 3 \\ 1
12 \\ (2^2) * 3 \\ 2
40 \\ (2^3) * 5 \\ 3 (endlicher Dezimalbruch. Periodenlänge = 0)
120 \\ (2^3) * 3 * 5 \\ 3
175 \\ (5^2) * 7 \\ 2 1/175 = 0,00 571428... 117/175 = 0,66 857142...
15.000 \\ (2^3) * 3 * (5^4) \\ 4
24.576 \\ (2^13) * 3 \\ 13
755.849 \\ 23 * 59 * 557 \\ 0
3.662.109.375 \\ 3 * (5^13) \\ 13

high(longint) ist übrigends +2.147.483.647 = (2^31) - 1 = Primzahl

Gruß
Lelf
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Do 12.04.12 19:15 
Hallo,

ich habe das in dem Programm periode.pas doch schon berücksichtigt.
Ich habe es nun etwas geändert, es wird ein '_' eingefügt, wo die Periode beginnt und endet und zum verständlich machen noch 5 Ziffern mehr ausgegeben.

Gruß Horst
Bei 175 startet die Periode 2 Stellen nach dem Komma und hat eine Länge von 6
Bei 176 startet die Periode 4 Stellen nach dem Komma und hat eine Länge von 2
ausblenden Quelltext
1:
2:
3:
4:
StartWert      175         2         6
0.00_571428_57142
StartWert      176         4         2
0.0056_81_81818
Einloggen, um Attachments anzusehen!