Technische Informatik für Ingenieure Winter 2006/2007

Werbung
Dr. Ekkart Kindler
FG Softwaretechnik
Institut für Informatik
Technische Informatik für Ingenieure
Winter 2006/2007 – Übungsblatt Nr. 1
4. Dezember 2006
Übungsgruppenleiter: K. Hojenski
M. Meyer
E. Münch
S. Pook
A. Znamenshchykov
D. Travkin
Seite 1(4)
Aufgabe 2:
(Der erste Algorithmus)
In der Vorlesung wurde ein Algorithmus für die Addition zweier positiver Zahlen vorgeführt
(siehe Vorlesungsunterlagen). Formulieren Sie diesen Algorithmus möglichst präzise in natürlicher Sprache.
Hinweis:
Die Lösung der Aufgabe könnte wie folgt beginnen:
1. Schreibe die erste der beiden zu addierenden Zahlen - mit den höherwertigen Ziffern
beginnend - von Links nach Rechts waagerecht in eine Zeile.
2. Schreibe darunter die zweite ...
Lösungsvorschlag:
1.
Gegeben sind zwei zu addierende Zahlen, wobei die größere durch die
Ziffernfolge xm xm-1 … x0 und die kleinere durch die Ziffernfolge yn yn-1 … y0
dargestellt wird.
2.
Schreibe zunächst die größere Zahl waagerecht als Ziffernfolge xm xm-1 … x0.
Schreibe dann die kleinere Zahl waagerecht als Ziffernfolge yn yn-1 … y0 unter die größere Zahl, so dass Ziffern yi unter Ziffern xi mit gleichem Index i stehen:
xm xm-1
yn
…
yn-1
…
xk
yk
xk-1
yk-1
…
…
x1
y1
x0
y0
3.
Schreibe darunter den Übertrag, der als Ziffernfolge uh uh-1 … u0 dargestellt wird:
Die Ziffern des Übertrags werden waagerecht unter die Ziffernfolge yn yn-1 … y0 geschrieben, so dass Ziffern ui wiederum unter Ziffern yi mit gleichem Index i stehen.
Die Ziffer u0 des Übertrags ist per Definition immer 0.
Der größte Index h der Ziffernfolge uh uh-1 … u0 ist genau um 1 größer als der größte Index m der Ziffernfolge xm xm-1 … x0: h = m+1.
4.
Notiere das Ergebnis als Ziffernfolge zj zj-1 … z0 analog zum Übertrag unter die Ziffernfolge uh uh-1 … u0: Ziffern ui des Übertrags und Ziffern des Ergebnisses zi mit gleichem Index i stehen untereinander.
Werden wie in dieser Aufgabe genau zwei Zahlen addiert, dann haben die Ziffernfolgen
uh uh-1 … u0 und zj zj-1 … z0 die gleiche Anzahl an Ziffern und für die größten Indizes h
und j gilt: h = j.
xm
uh uh-1
zj zj-1
5.
xm-1
yn
…
…
…
yn-1
…
xk
yk
uk
zk
xk-1
yk-1
uk-1
zk-1
…
…
…
…
x1
y1
u1
z1
x0
y0
0
z0
Addiere mit dem kleinsten Index i = 0 beginnend von rechts nach links fortschreitend die
Ziffern xi und yi:
Beginne mit der Addition von x0 und y0. Das Ergebnis hat höchstens zwei Stellen: e1 e0.
Technische Informatik für Ingenieure – Übungsblatt 1
Seite 2(4)
Schreibe die erste, kleinere Stelle e0 als Ergebnis z0.
Notiere die zweite Stelle e1 als Übertrag u1. Falls das Ergebnis nur eine Stelle e0 benötigt, ist der Übertrag u1 = 0.
Fahre fort mit der Addition von x1, y1 und dem Übertrag u1. Das Ergebnis hat wiederum
höchstens zwei Stellen e1 und e0.
Notiere e0 als Ergebnis z1 und e1 als Übertrag u2. Falls das Ergebnis nur eine Stelle e0
benötigt, ist der Übertrag u2 = 0.
Fahre fort mit der Addition von xi, yi und dem Übertrag ui. Falls der Index i größer ist als
der größte Index n der Ziffernfolge yn yn-1 … y0, addiere lediglich xi und ui.
Wiederum hat das Ergebnis höchstens zwei Stellen e1 und e0. Notiere e0 als Ergebnis zi
und e1 als Übertrag ui+1.
Falls das Ergebnis nur eine Stelle e0 benötigt, ist der Übertrag ui+1 = 0.
Wiederhole diesen Schritt mit aufsteigendem Index i, solange der Index i kleiner oder
gleich dem größten Index m der Ziffernfolge xm xm-1 … x0 ist.
Nach Abarbeitung der Ziffernfolge xm xm-1 … x0 übertrage den Übertrag uh als Ziffer zj des
Ergebnisses zj zj-1 … z0.
Aufgabe 4 d):
(Das erste Java-Programm)
Protokollieren Sie das Verhalten des Programms bei der Eingabe von sehr großen und sehr
kleinen Zahlen. Was passiert, wenn negative Zahlen eingegeben werden? Wann wird das
Ergebnis „0“? Wann wird das Ergebnis falsch?
Eingabe sehr großer Zahlen:
Bis zur Eingabe der Zahl 12 gibt das Programm ein korrektes Ergebnis aus:
Geben Sie eine natuerliche Zahl ein: 12
Das Ergebnis ist 479001600.
Die Eingabe der Zahl 13 führt zum ersten falschen Ergebnis:
Geben Sie eine natuerliche Zahl ein: 13
Das Ergebnis ist 1932053504.
(Richtig wäre das Ergebnis 13! = 6227020800).
Erklärung:
Bei Java werden ganzzahlige Werte mit dem Datentyp Integer gespeichert. Zur Speicherung
einer Integer-Zahl stehen bei Java 32 Bit zur Verfügung. Von diesen 32 Bit wird ein Bit zur
Speicherung des Vorzeichens benötigt, so dass zur Darstellung der Zahl effektiv 31 Bit zur
Verfügung stehen. Zusätzlich muss die 0 dargestellt werden. Daher ist die größte darstellbare
positive Zahl um genau 1 kleiner als die größte darstellbare negative Zahl:
Größte darstellbare positive Zahl:
Größte darstellbare negative Zahl:
231-1 = 2147483647
231 = -2147483648
Bei Java können die größte positive und die größte negative Zahl mit
Integer.MAX_VALUE und Integer.MIN_VALUE ermittelt werden:
Integer.MAX_VALUE: 2147483647
Integer.MIN_VALUE: -2147483648
Werden diese Werte über- oder unterschritten, dann tritt ein Überlauf auf: Die Zahl kann nicht
mehr vollständig dargestellt werden, nur die letzten 31 Bit werden korrekt gespeichert. Die
höheren Bit gehen verloren. Das Vorzeichen-Bit wird durch Bit 32 der zu speichernden Zahl
ersetzt. Dieser Effekt kann bei Eingabe der Zahl 17 beobachtet werden:
Geben Sie eine natuerliche Zahl ein: 17
Das Ergebnis ist -288522240.
Technische Informatik für Ingenieure – Übungsblatt 1
Seite 3(4)
Ausgabe der „0“ als Ergebnis
Die Eingabe einer Zahl größer gleich 34 führt zum Ergebnis „0“:
Geben Sie eine natuerliche Zahl ein: 34
Das Ergebnis ist 0.
Erklärung:
Der oben beschriebene Effekt lässt sich durch die interne Darstellung von Integer-Zahlen
durch Java erklären:
Eine 32 Bit große Integer-Zahl ist eine 32-stellige Folge binärer Ziffern. Um positive und negative Zahlen darstellen zu können, verwendet Java das Zweierkomplement:
Integer.MAX_VALUE = 2147483647 = 0111…111
Integer.MIN_VALUE = -2147483648 = 1000…000
Das höchstwertige Bit (Bit mit Index 32) legt dabei das Vorzeichen fest: „0“ für eine positive
Zahl, „1“ für eine negative Zahl.
Die Dezimalzahl „0“ wird repräsentiert durch: 0 = 0000…000.
Bei der Berechnung der Fakultät für die Zahl n werden n Multiplikationen durchgeführt. Dabei
wird das Zwischenergebnis im ständigen Wechsel mit einer geraden und einer ungeraden
Zahl multipliziert. Durch die Multiplikation mit geraden Zahlen werden die Binärziffern vom
Index 0 beginnend mit steigendem Index nacheinander zu „0“.
Bei der Berechnung der Fakultät sind nach 32 Schleifendurchläufen die ersten 31 Stellen mit
„0“ belegt und das Vorzeichen (Bit 32) auf „1“ gesetzt: Die größte darstellbare negative Zahl
ist erreicht. Findet nun eine Multiplikation mit einer ungeraden Zahl statt (was bei der letzten
Multiplikation zur Berechnung von 33! Der Fall ist), dann ändert sich an der Belegung im
Speicher nichts. Wird die größte darstellbare negative Zahl hingegen mit einer geraden Zahl
multipliziert, dann wird Bit 32 zu „0“. Da die restlichen Speicherzellen bereits mit „0“ belegt
sind, entspricht diese Belegung genau der Darstellung der Dezimalzahl „0“.
Das folgende Programm verdeutlicht diese Effekte:
public class Ueberlauf {
public static void main(String[] args) {
int i = Integer.MAX_VALUE;
Out.println("Integer.MAX_VALUE:
" + i);
i += 1;
Out.println("Integer.MAX_VALUE + 1: " + i);
i = Integer.MAX_VALUE;
i *= 3;
Out.println("Integer.MAX_VALUE * 3: " + i);
i = Integer.MAX_VALUE;
i *= 2;
Out.println("Integer.MAX_VALUE * 2: " + i);
Out.println();
i = Integer.MIN_VALUE;
Out.println("Integer.MIN_VALUE:
" + i);
i -= 1;
Out.println("Integer.MIN_VALUE - 1: " + i);
i = Integer.MIN_VALUE;
i *= 3;
Out.println("Integer.MIN_VALUE * 3: " + i);
Technische Informatik für Ingenieure – Übungsblatt 1
Seite 4(4)
i = Integer.MIN_VALUE;
i *= 2;
Out.println("Integer.MIN_VALUE * 2: " + i);
}
}
Ausgabe des Programms:
Integer.MAX_VALUE:
2147483647
Integer.MAX_VALUE + 1: -2147483648
Integer.MAX_VALUE * 3: 2147483645
Integer.MAX_VALUE * 2: -2
Integer.MIN_VALUE:
-2147483648
Integer.MIN_VALUE - 1: 2147483647
Integer.MIN_VALUE * 3: -2147483648
Integer.MIN_VALUE * 2: 0
Eingabe der Zahl 0:
Für die Eingabe der Zahl 0 gibt das Programm das Ergebnis 1 aus, was nach Definition der
Fakultät richtig ist:
Geben Sie eine natuerliche Zahl ein: 0
Das Ergebnis ist 1.
Erklärung:
Die Bedingung der Schleife wird für n = 0 nicht erfüllt. Daher wird die Schleife in diesem Fall
nicht durchlaufen und der Initialisierungswert von Erg ausgeben. Der Initialisierungswert von
Erg ist im Programm auf 1 gesetzt.
Eingabe negativer Zahlen:
Für die Eingabe negativer Zahlen gibt das Programm das Ergebnis 1 aus. Fakultäten sind nur
für natürliche Zahlen und 0 definiert. Daher ist dieses Ergebnis streng genommen falsch.
Richtig wäre z.B. die Ausgabe:
Geben Sie eine natuerliche Zahl ein: -1
Fakultäten für negative Zahlen sind nicht definiert.
Diese Ausgabe ließe sich durch Erweiterung des Programms um eine Bedingung erzeugen:
Out.print("Geben Sie eine natuerliche Zahl ein: ");
int n = In.readInt();
// weitere Initialisierungen
if (n >= 0)
{
// Berechnung der Fakultät hier einfügen
Out.println("Das Ergebnis ist " + erg + ".");
}
else
{
Out.println("Fakultäten für negative Zahlen sind nicht definiert.");
}
Herunterladen