Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Frage zu Algorithmus

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
27.09.2012, 10:23 Uhr
fetches



Hallo!
Bitte seht mal über den Algorithmus und sagt mir, ob der so ok ist oder ob der weiter verbessert werden kann. (Zur Info: Ich habe erst vor einigen Tagen angefangen C++ zu lernen und bin jetzt erst einmal bei der Entwicklung von Algorithmen...)

Ziel ist, daß mit dem Algorithmus der Wert einer Zahl b^n ermittelt wird.

Vorüberlegungen meinerseits:
1.)Anwenderseitig wird die Basis und der Exponent benötigt.
2.) Programmseitig wird ein Schleifenzähler (Durchlaufzähler oder wie immer das heißt *?) benötigt, sowie eine Variable für die Ablage des Zwischenergebnisses.

Bezeichnungen:
b = Basis
n = Exponent
i = Schleifenzähler
z = Zwischenergebnis

Algorithmus:

Eingabe b
Eingabe n
Setze i = 1
Setze z = b
Wiederhole
z = z * b
i = i ++
Bis i = n
Ausgabe z

Um die Berechnung des Exponents 1 zu sparen habe ich i = 1 gesetzt. Da b^1=b ist und dies das erste Zwischenergebnis habe ich z = b gesetzt. Ist das sowiet korrekt bzw. paßt das überhaupt?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
27.09.2012, 10:39 Uhr
ao

(Operator)


Er ist falsch. Spiele ihn Schritt für Schritt durch für

b = irgendwas (z.B. 2) und
n = 1.

Du wirst merken: Wenn du die Abbruchbedingung zum 1. Mal prüfst, ist i schon inkrementiert und steht auf 2. Die Bedingung ist nicht erfüllt, und du kommst in eine Quasi-Endlosschleife, die nur deshalb doch noch abbricht, weil i irgendwann überläuft.

Abhilfen:
1. Abweisende Schleife verwenden (Bedingung beim Eintritt, nicht beim Austritt)
2. Bei i = 0 anfangen. Das kostet zur Laufzeit praktisch nichts, und über Sonderfälle nachdenken zu müssen ist immer schlecht.

Was auch nicht geht: n < 0. Ist zum Üben nicht tragisch, muss dir aber bewusst sein. Du solltest alles, womit der Algo nicht umgehen kann, zu Beginn abfangen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
27.09.2012, 12:53 Uhr
fetches



Danke für den Hinweis mit Exponent = 0. Daran hatte ich gar nicht mehr gedacht.
Als weitere Vorüberlegung kommt also hinzu, daß alle x^0 = 1 ergeben, womit also die Variable Zwischenergebnis z = 1 anfangs gesetzt wird. (Richtig?)
Alle anderen Vorüberlegungen gelten weiterhin.

Neuer Algorithmus:

Basis b eingeben
Exponent n eingeben
Setze Durchlaufzahl i = 0
Setze Zwischenergebnis z = 1
Solange i != n
z = z * b
i = i ++
Ausgabe Zwischenergebnis z

Bsp 1: 2^0 = 1
b = 2
n = 0
i = 0
z = 1

0 != 0 --> falsch, Abbruch, Ausgabe z = 1

Bsp 2: 2^2 = 4

b = 2
n = 2
i = 0
z = 1

0 != 2 --> wahr
z = 1 * 2 = 2 --> Stellt also die Berechnung 2^1 dar.
i = 0++ = 1

1 != 2 --> wahr
z = 2 * 2 = 4 --> Stellt also die Berechnung 2^2 dar.
i = 1++ = 2

2 != 2 --> falsch, Abbruch, Ausgabe z = 4

Ist das so richtig oder habe ich wieder einen Denkfehler?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
27.09.2012, 15:33 Uhr
ao

(Operator)


Jetzt ist er im Prinzip richtig (glaube ich) - bis auf diese Stelle:


C++:
    i = i++;



Lies hierzu mal kurz das: http://c-faq.com/expr/ieqiplusplus.html und das Drumherum.

Das ist schon fortgeschrittenes Zeug, Sequenzpunkte und so. Wirst du wahrscheinlich noch nicht verstehen.

Merk dir einfach, dass i++ allein bereits ausreicht, um i zu inkrementieren. Ebenso ++i; und i = i + 1;

i = i++; hingegen ist doppelt gemoppelt und kann Unsinn erzeugen.

Der Hintergrund ist, dass Mikroprozessoren in der Regel nicht in der Lage sind, eine Variable direkt im RAM zu inkrementieren. Sondern sie laden den Wert in ein internes Arbeitsregister, inkrementieren ihn dort und schreiben ihn in den Speicher zurück.

Der Ausdruck i = i++; ist nun bezüglich der Reihenfolge der Aktionen nicht eindeutig. Es ist dem Compiler überlassen, ob er den Wert im Arbeitsregister (das i rechts des Gleichheitszeichens) erst inkrementiert und dann zurückschreibt oder umgekehrt (in diesem Fall würde der Wert im RAM nicht verändert und der Wert im Register nach Inkrementierung verworfen).
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
27.09.2012, 16:05 Uhr
fetches



Ah! Mit der Erklärung ging mir jetzt das Licht auf, warum ich immer nur i++ lese. Interessant ist auch, was an welcher Stelle wo gespeichert wird. Ist der Speichervorgang immer so? Kennst du evtl. noch Ressourcen, die den technischen Hintergrund normal verständlich für Otto Normalo erklären?

Danke dir für deine Hilfe.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
28.09.2012, 08:52 Uhr
ao

(Operator)



Zitat von fetches:
Interessant ist auch, was an welcher Stelle wo gespeichert wird. Ist der Speichervorgang immer so?

Was meinst du damit?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
28.09.2012, 15:33 Uhr
fetches



Du hast geschrieben:

Zitat:
Es ist dem Compiler überlassen, ob er den Wert im Arbeitsregister...


Aus meiner Sicht ist das die Beschreibung eines technischen Vorgangs, hier: Welcher Wert wird wohin gespeichert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: