zurück

Zyklische Zahlen (III)

C. 2 Word-Makros

I. Charakterisierung

1.       Das erste Makro ermittelt zyklische Zahlen und trennt sie von den übrigen Primzahlen. Sie werden in eine Datei c:/zypz.txt geschrieben und mit "zy" bzw. "pr" gekennzeichnet.

2.       Das zweite Makro ermittelt das Verhältnis von zyklischen Zahlen 1. Ordnung und höherer Ordnung. Sie werden aus c:/zypz.txt ausgelesen, die Verhältnisse auf dem Bildschirm ausgegeben. Überprüfen Sie, daß zypz.txt nicht mit einer leeren Absatzmarke abgeschlossen wird. Ich habe mir die diesbezüglichen Abfrageanweisungen erspart.

Der Programmteil ersetzt "zy" und "pr" durch gr1$ und gr2$. Auf diese Weise können Zahlengruppen auch ein anderes "Präfix" erhalten. Die beiden Präfixe "zy" und "pr" sind am Anfang als gr1$ und gr2$ deklariert. Es ist zu beachten, daß das Makro immer mit gr2$ beginnt. Da die Reihenfolge der Zahlen keine Rolle spielt, stellt man an die Spitze eine Zahl mit der Kennzeichnung unter gr2$.

3.       Beide Makros bestehen aus einem kommentierten Teil und dem eigentlichen Programmteil. Der kommentierte Teil ist unter Word 7 programmiert, der Programmteil ist unter Word 2000 konvertiert.

4.       Falls Sie nicht wissen, wie die Makros erstellt werden, gebe ich den Weg an:

Kopieren Sie das Makro in die Zwischenablage. Dann gehen Sie zu Menü Extras > Makro > Makros. Geben Sie in die Eingabezeile einen beliebigen Namen mit der Erweiterung .MAIN (z.B. a.MAIN) für das Makro an und drücken auf Erstellen. Löschen Sie den vorgegebenen Eintrag und fügen Sie den Inhalt der Zwischenablage ein. Drücken Sie auf das Speichersymbol und schließen Sie Visual-Basic.

Nun können Sie das Makro laufen lassen. Leider weiß ich bis heute nicht, wie man ein Endlosmakro und Word 2000+ anders als durch Strg-Alt-Entf beenden kann. Da das erste Makro die Ergebnisse in eine Datei schreibt, geht durch die erzwungene Schließung des Programms nichts verloren. Sichern Sie sich unbedingt die Textdatei mit den zyklischen Zahlen.

Wenn Sie zu einem anderen Zeitpunkt das Programm fortsetzen wollen, geben Sie die letzte Zahl der Textdatei + 2 unter der numerischen Variablen z ein, u.U. können Sie auch eine anderen Dateinamen wählen.

II. Makrodokumentierung

1a) Kommentierung

'Basisprogramm zur Ermittlung von zyklischen Zahlen

Dim Shared z, n

Sub MAIN

z = 7:n = 3

Gegeben sind die ersten 4 Primzahlen 1,2,3,5

'z = die zu teilende ungerade Zahl, die um jeweils 2 Zähler fortschreitet; 7 ist die erste zu berechnende Zahl

'n = 3: der erste ungerade Divisor, der um jeweils 2 Zähler fortschreitet

einfügen "pr" + Mid$(Str$(1), 2): EinfügenAbsatz

einfügen "pr" + Mid$(Str$(2), 2) :EinfügenAbsatz

einfügen "pr" + Mid$(Str$(3), 2) : EinfügenAbsatz

einfügen "pr" + Mid$(Str$(5), 2) :EinfügenAbsatz)

'Die ersten 4 Zahlen werden vorgegeben und mit "pr" bezeichnet. Die Zahl 3 ist zyklisch 2. Ordnung.

start:

If z > 1000 Then Goto ENDE

e = z / n

'e = Teilungsergebnis, es ist immer eine Dezimalzahl

If Int(e) <> e Then

'Int() liefert den ganzzahligen Teil einer Dezimalzahl

If n * n > z Then

UPZYK

Goto START

Else

'Wenn das Teilungsergebnis eine ganze Zahl ist, ist die geteilte Zahl keine Primzahl und die übernächste Zahl wird geteilt

n = n + 2 : Goto START

EndIf

Else

z = z + 2 : n = 3 : Goto START

EndIf

ende:

End Sub

'------------------

Sub UPZYK

'Es wird untersucht, ob die ermittelte Primzahl eine zyklische Zahl 1. Ordnung ist.

r = 1

'r = Rest; r = 1: die erste Stelle 1 ist als erster Rest anzusehen, der am Ende der Teilungen wiederkehrt

stz = Len(Mid$(Str$(z), 2))

'stz = Stellenzahl. Die Periodik einer zyklischen Zahl p (1. Ordnung) besteht aus p-1 Stellen. Sie wird aus der Zahl 10p-1 ermittelt. Die erste Teilung des Programms überspringt die Nullen nach dem Komma, die jeweils um einen Zähler weniger als die Stellenzahl der zu teilenden Zahl betragen, z.B. 23: nach dem Komma steht 2-1=1 Null: 0,043...

For i = 1 To stz

r = r * 10

Next

'Die Zahl, durch die z geteilt wird besteht aus 1 + n Nullen. n ist gleich der Stellenzahl von z., z.B. 10/7.

div = r / z

'div: Teilungsergebnis, gleichbedeutend mit der Variablen e des Hauptprogramms

rest = r - Int(div) * z

'z.B. 10/7 = 1,42857; 10-(1*7) = 3; rest = 3

While rest > 1

div = rest * 10 / z

stz = stz + 1

rest = rest * 10 - Int(div) * z

If stz > (z - 1) / 2 Then

einfügen "zy" + Mid$(Str$(z), 2) : Print Str$(z):EinfügenAbsatz

Goto WEITER

EndIf

'if: Sobald die Stellenzahl für eine zyklische Zahl 2. Ordnung überschritten ist, handelt es sich um eine zyklische Zahl 1. Ordnung. Die Zahl 13 z.B. ist eine Zahl 2. Ordnung, ihre Stellenzahl (13-1)/2 = 6. Der if-Einschub verkürzt die Ermittlung von zyklischen Zahlen 1. Ordnung um die Hälfte. Die zyklischen Zahlen 1. Ordnung erhalten die Kennzeichnung "zy".

Wend

Einfügen "pr" + Mid$(Str$(z), 2):EinfügenAbsatz

'Die zyklischen Zahlen höherer Ordnung erhalten die Kennzeichnung "pr".

WEITER:

z = z + 2 : n = 3

End Sub

1b) Programm

Dim z, n

Public Sub MAIN()

Dim e

z = 0

n = 0

z = 7: n = 3

Open "c:/zykpmz.txt" For Output As 1

Print #1, "pr" + Mid(Str(1), 2)

Print #1, "pr" + Mid(Str(2), 2)

Print #1, "pr" + Mid(Str(3), 2)

Print #1, "pr" + Mid(Str(5), 2)

start:

e = z / n

If WordBasic.Int(e) <> e Then

If n * n > z Then

UPZYK

GoTo start

Else

n = n + 2: GoTo start

End If

Else

z = z + 2: n = 3: GoTo start

End If

ende:

End Sub

'------------------

Private Sub UPZYK()

Dim r

Dim stz

Dim i

Dim div

Dim rest

r = 1

stz = Len(Mid(Str(z), 2))

For i = 1 To stz

r = r * 10

Next

div = r / z

rest = r - WordBasic.Int(div) * z

While rest > 1

div = rest * 10 / z

stz = stz + 1

rest = rest * 10 - WordBasic.Int(div) * z

If stz > (z - 1) / 2 Then

Print #1, "zy" + Mid(Str(z), 2): WordBasic.PrintStatusBar Str(z)

GoTo WEITER

End If

Wend

Print #1, "pr" + Mid(Str(z), 2): WordBasic.PrintStatusBar Str(z)

WEITER:

z = z + 2: n = 3

End Sub

 

2a) Kommentierung

'Dieses Programm liest zyklische Zahlen 1. und höherer Ordnung aus einer Datei und stellt ihr Zahlenverhältnis zu einander fest. Die zyklischen Zahlen sind mit "zy" am Anfang (ohne Leerzeichen), die übrigen Primzahlen mit "pr" gekennzeichnet. Nach dem Wechsel eines Zahlengruppe bleibt die letzte Zahl der ersten Gruppe "stehen", während die Zahlen der zweiten Gruppe so lange fortschreiten, bis die nächste Zahl der ersten Gruppe eingelesen ist. Jede der fortschreitenden Zahlen wird mit der stehenden Zahl ins Verhältnis gesetzt. Z.B. bleibt die 5. zyklische Zahl 29 stehen, während die nicht-zyklischen Zahlen 1. Ordnung 31, 37, 41, 43 fortschreiten. Die Zahl 37 ist die 8. nicht-zyklische Zahl 1. Ordnung, daher bildet sie mit der zyklischen Zahl 29 das Verhältnis 8:5.

 

Dim Shared zy$, pr$, zyk$, prz$, zyn, prn

Sub MAIN

FormatTabulator .AlleLösch

FormatTabulator .Position = "2 cm", .Ausrichten = 0, .Bestimmen

FormatTabulator .Position = "4 cm", .Ausrichten = 0, .Bestimmen

Open "c:/ww2/werte/zykpz.txt" For Input As #1

Line Input #1, zypz$

prn = prn + 1

'prn = Nummer der Primzahlen: Die Zahlen 1,2,5 sind nicht zyklisch und können frei auf die beiden Gruppen aufgeteilt werden. Das Programm rechnet sie den zyklischen Zahlen höherer Ordnung zu.

While Left$(zypz$, 2) = "pr"

prn = prn + 1

Line Input #1, zypz$

pr$ = zypz$

Wend

prn = prn - 1

'While-Wend stellt erst nach Einlesen des anderen Zahlentyps den Wechsel fest, daher muß die Zählung um 1 zurückgesetzt werden. Diese erste While-Wend -Schleife gilt nur für den Anfang der Zählung, daher liegt START: vor der zweiten WW-Schleife.

zy$ = zypz$ : zyn = zyn + 1

'Die eingelesene Zahl wird dem zweiten Typ zy$ hinzugerechnet.

START:

While Left$(zypz$, 2) = "zy"

Line Input #1, zypz$

zyn = zyn + 1

If Left$(zypz$, 2) = "zy" Then

zy$ = zypz$ : zyk$ = zy$ : UPFZ

'zy$ wird zu zyk$ weiter umbenannt, da zypz$ durch das Einlesen einer weiteren Zahl neu bestimmt wird. Dasselbe gilt für pr$ imd prz$. Im Unterprogramm Faktorenzerlegung UPFZ wird das Verhältnis der fortschreitenden Zahl zur stehenden Zahl ermittelt.

EndIf

Wend

zyn = zyn - 1

pr$ = zypz$ : prz$ = pr$ : prn = prn + 1 : UPFZ

While Left$(zypz$, 2) = "pr"

Line Input #1, zypz$

prn = prn + 1

pr$ = zypz$

If Left$(zypz$, 2) = "pr" Then

pr$ = zypz$ : prz$ = pr$

UPFZ

EndIf

Wend

prn = prn - 1

zy$ = zypz$ : zyk$ = zy$ : zyn = zyn + 1 : UPFZ

Goto START

'Die beiden Zahlentypen wechseln sich mit gleichem Muster in zwei WW-Schleifen ab.

ende:

End Sub

'------------------

Sub UPFZ

'Stop : Print zyn, prn, zyk$, prz$

Dim f(30)

'f() = Einlesen von Faktoren

z = zyn : p = prn

'Umbenennung zu z und p, um aktuellen Inhalt von zyn und prn zu erhalten.

'Die Faktorenzerlegung wird an der kleineren zyklischen Anzahl z vorgenommen.

START1:

e = z / 2

'Sonderbehandlung der geraden Zahl 2, danach Wechsel zu ungeraden Zahlen mit 3 und d = d+2

Print e, z

If e = Int(e) Then

n = n + 1 : f(n) = 2

z = z / 2

Goto START1

Else

Print n

d = 3

'd = divisor

EndIf

START2:

e = z / d

If e = Int(e) Then

n = n + 1 : f(n) = d

z = z / d

Print n, z

Goto START2

Else

d = d + 2

If d * d > z Then

n = n + 1 : f(n) = z

ElseIf z = d Then

n = n + 1 : f(n) = d

Else

Goto START2

EndIf

EndIf

'Programm zur Ermittlung gemeinsamer Faktoren

'Die gefundenen Faktoren werden mit den Faktoren der größeren Primzahlanzahl p verglichen.

gem = 1 : z = 1

'gem = gemeinsame Faktoren, z = Faktoen, die nicht in p enthalten sind.

1 ist Multiplikationsfaktor, p = jeweiliger Rest

For i = 1 To n

e = p / f(i)

If e = Int(e) Then

gem = gem * f(i) : p = p / f(i)

Else

z = z * f(i)

EndIf

Next

If gem > 50 Then

'Die Größe der gemeinsamen Faktoren kann hier eingestellt werden.

Einfügen Mid$(Str$(z), 2) + Chr$(9) + Mid$(Str$(p), 2) + Chr$(9) + Mid$(Str$(gem), 2)

Einfügen Chr$(9) + zyk$ + Chr$(9) + prz$

'Der Reihe nach werden ausgegeben: die Verhältniszahlen der kleineren und der größeren Gruppe, die gemeinsamen Faktoren, die letzte Zahl der jeweiligen Gruppe. Die dazwischen stehenden Tabulatoren ermöglichen die Umwandlung in eine Tabelle mit entsprechenden Sortiermöglichkeiten.

EinfügenAbsatz

EndIf

End Sub

 

2b) Programm

Dim zy$, pr$, zyk$, prz$, zyn, prn

Public Sub MAIN()

Dim gr1$

Dim gr2$

Dim zypz$

zy$ = ""

pr$ = ""

zyk$ = ""

prz$ = ""

zyn = 0

prn = 0

gr1$ = "zy": gr2$ = "pr"

Close

On Error GoTo -1: On Error GoTo ende

Open "c:/zypz.txt" For Input As 1

Line Input #1, zypz$

If zypz$ = "" Then GoTo ende

prn = prn + 1

While WordBasic.[Left$](zypz$, 2) = gr2$

prn = prn + 1

Line Input #1, zypz$

pr$ = zypz$

Wend

prn = prn - 1

zy$ = zypz$: zyk$ = zy$: zyn = zyn + 1

START:

While WordBasic.[Left$](zypz$, 2) = gr1$

Line Input #1, zypz$

zyn = zyn + 1

If WordBasic.[Left$](zypz$, 2) = gr1$ Then

zy$ = zypz$: zyk$ = zy$: UPFZ

End If

Wend

zyn = zyn - 1

pr$ = zypz$: prz$ = pr$: prn = prn + 1: UPFZ

While WordBasic.[Left$](zypz$, 2) = gr2$

Line Input #1, zypz$

prn = prn + 1

pr$ = zypz$

If WordBasic.[Left$](zypz$, 2) = gr2$ Then

pr$ = zypz$: prz$ = pr$

UPFZ

End If

Wend

prn = prn - 1

zy$ = zypz$: zyk$ = zy$: zyn = zyn + 1: UPFZ

GoTo START

ende:

End Sub

'------------------

Private Sub UPFZ()

Dim z

Dim p

Dim e

Dim n

Dim d

Dim gem

Dim i

ReDim f__(30)

z = zyn: p = prn

START1:

e = z / 2

If e = WordBasic.Int(e) Then

n = n + 1: f__(n) = 2

z = z / 2

GoTo START1

Else

d = 3

End If

START2:

e = z / d

If e = WordBasic.Int(e) Then

n = n + 1: f__(n) = d

z = z / d

GoTo START2

Else

d = d + 2

If d * d > z Then

n = n + 1: f__(n) = z

ElseIf z = d Then

n = n + 1: f__(n) = d

Else

GoTo START2

End If

End If

gem = 1: z = 1

For i = 1 To n

e = p / f__(i)

If e = WordBasic.Int(e) Then

gem = gem * f__(i): p = p / f__(i)

Else

z = z * f__(i)

End If

Next

If gem > 50 Then

WordBasic.Insert Mid(Str(z), 2) + Chr(9) + Mid(Str(p), 2) + Chr(9) + Mid(Str(gem), 2)

WordBasic.Insert Chr(9) + zyk$ + Chr(9) + prz$

WordBasic.InsertPara

End If

End Sub

 

 

 

 

 

 

 

 

 

 

 

 

 

Erstellt: Februar 2006

Inhalt