# BigInteger und StringBuffer



## Augustiner (15. Dez 2010)

Hi Leute,
ich sitze schon seit Tagen an einer Aufgabe und bekomm sie einfach nicht gebacken...
vieleicht kann mir jemand helfen.???:L

Vorbereitung
Legen Sie in Ihrem Workspace ein Projekt  an, in dem Sie die Lösungen zu den Aufgaben dieses
Blattes implementieren.
Aufgabe 1 beschreibt die Implementierung der Klasse BigInteger. Aufgabe 2 fokussiert die Entwicklung der
Klasse ApplicationBigInteger mit dem entsprechenden Hauptprogramm, mit Hilfe dessen Sie die Klasse
BigInteger testen können. Entwickeln Sie die beiden Klassen nebeneinander, d.h. implementieren Sie Ihre Klasse
ApplicationBigInteger so weit mit, dass Sie damit die neuen Eigenschaften Ihrer Klasse BigInteger
sukzessive testen können.
*Aufgabe 1:* Große Zahlen
Die feste Länge der primitiven Datentypen int, long für Ganzzahlwerte und float, double für Fließkommawerte
reicht für diverse numerische Berechnungen nicht aus. Besonders wünschenswert sind beliebig große Zahlen in
der Kryptographie und präzise Auflösungen in der Finanzmathematik. Für solche Anwendungen gibt es im math-
Paket zwei Klassen: BigInteger für Ganzzahlen und BigDecimal für Gleitkommazahlen.
*a)* Entwickeln Sie eine Klasse BigInteger zur Darstellung sehr großer positiver Zahlen. Verwenden Sie hierzu,
das zur Verfügung gestellte Template. Ein BigInteger-Objekt speichert die Darstellung einer großen Zahl in
einem StrringBuffer. Die Klasse StringBufffer ermöglicht die Speicherung und Verarbeitung beliebiger
Zeichenreihen. Für das Arbeiten mit dem StringBuffer beachten Sie bitte die Hilfsmittel in dem Template.
*b)* Definieren Sie einen Konstruktor für den Wert null - BigInteger()
*c)* Definieren Sie einen Konstruktor für den Wert einer ganzen Zahl n - BigInteger(int n)
*d) *Definieren Sie einen Konstruktor, der den Wert aus einer Zeichenkette einliest – BigInteger(String s)
*e)* Implementieren Sie eine Methode add(BigInteger b). Diese liefert als Rückgabewert die Summe der Zahl
BigInteger b und der Zahl welche durch das instantiierte Objekt der Klasse dargestellt wird. Die Methode
addiert Zahlen stellenweise nach dem Schema der schriftlichen Addition, wie es den Grundschülern
beigebracht wird. Falls nötig implementieren Sie weitere Methoden. Zum Auslesen der einzelnen Ziffern
verwenden Sie die Methode getDigit(int p).
*f)* Implementieren Sie eine Methode print(), welche die Ausgabe einer großen Zahl auf der Konsole
ermöglicht.
*Aufgabe 2:* Hauptprogramm
Implementieren Sie eine Klasse ApplicationBigInteger zur Steuerung Ihrer Applikation. Verwenden Sie
hierzu das zur Verfügung gestellte Template. Zum Einlesen der großen Zahlen verwenden Sie die bereits
implementierte Methode readConsole()
*a)* Implementieren Sie im Hauptprogramm eine Methode sumBigInteger(int pNumber) – die Methode ruft
pNumber – mal die Methode readConsole() zum Einlesen von großen Zahlen ein und gibt beim Aufruf die
Seite 2 von 2
Summe dieser Zahlen zurück. Zum Aufaddieren der Zahlen verwenden Sie die Methode add(BigInteger b) der Klasse BigInteger.
*b)* Testen Sie mit Hilfe der main(String[] args) Methode, die Methode sumBigInteger(int pNumber). Zum
Einlesen von pNumber, verwenden Sie die bereits vorimplementierte Abfrage. Deklarieren Sie den
BigInteger sumBI welcher seinen Wert aus sumBigInteger(int pNumber) erhält. Geben Sie den Wert vom
SumBI mit Hilfe der Methode print() der Klasse BigInteger auf der Konsole aus.
*c)* Testen Sie Ihre Anwendung, für die Zahlen:
- 5.000.000.000.000, 5.000.000.000.000
- 123456789 und 987654321
- 111.111.111.111, 222.222.222.222, 333.333.333.333 und 333.333.333.334
*Die Ausgabe Ihres Programms sollte in etwa so aussehen:*
Wieviele Zahlen sollen aufaddiert werden?
2
Bitte geben Sie eine Zahl ein!
5000000000000
Bitte geben Sie eine Zahl ein!
5000000000000
Die Summe der 2 Zahlen, die Sie eingeben haben, ist:
10000000000000
Wieviele Zahlen sollen aufaddiert werden?
2
Bitte geben Sie eine Zahl ein!
123456789
Bitte geben Sie eine Zahl ein!
987654321
Die Summe der 2 Zahlen, die Sie eingeben haben, ist:
1111111110
Wieviele Zahlen sollen aufaddiert werden?
4
Bitte geben Sie eine Zahl ein!
111111111111
Bitte geben Sie eine Zahl ein!
222222222222
Bitte geben Sie eine Zahl ein!
333333333333
Bitte geben Sie eine Zahl ein!
333333333334
Die Summe der 4 Zahlen, die Sie eingeben haben, ist:
1000000000000


----------



## SlaterB (15. Dez 2010)

helfen heißt 'du postest die Aufgabe, andere die Lösung'?
oder willst du noch Gedankengänge, eigenen Code, konkrete Probleme beschreiben?


----------



## Landei (15. Dez 2010)

Laut Vorlage wird ein StringBuffer dazu missbraucht, die Ziffern deiner Zahl zu speichern (was ich rein persönlich für eine schlechte Idee halte). Zumindest werden die Ziffern rückwärts gespeichert, ansonsten hättest du ziemlich zu knabbern.

Ich bin mal nicht so und mach dir den int-Konstruktor:

```
public BigInteger(int n) {
   if (n < 0) {
      throw new IllegalArgumentException("Nur nicht-negative Zahlen erlaubt!");
   }
   digits.append(n).reverse();
}
```

Beim Rest musst du schon selber sagen, wo du nicht weiter kommst. Ohne ein bisschen Eigeninitiative wird das nichts...


----------



## Augustiner (15. Dez 2010)

Der Einstieg würde mir ja schon weiter helfen ......ich komm mit den Kommentaren in der Vorlage BigInteger nicht klar...


----------



## SlaterB (15. Dez 2010)

Landei hat ja schon was gepostet, ansonsten stell dir vor es gäbe die ganzen Kommentare nicht,
was würdest du als erstes umsetzen, weitere Konstruktoren oder was noch, wo besteht ein Problem und welches?

dass jede Ziffer als String-char-Zeichen im StringBuffer gespeichert werden soll, muss natürlich grundlegend vorher verstanden sein


----------



## Augustiner (15. Dez 2010)

diese Kommentare sind mein Problem...   muss man nichts davon implementieren oder wie?


----------



## SlaterB (15. Dez 2010)

lös doch einfach die Aufgabe
> b) Definieren Sie einen Konstruktor für den Wert null - BigInteger()


----------



## Augustiner (15. Dez 2010)

kann mann das so schreiben oder ist das Blödsinn???

```
public class BigInteger {
	
	//Zeichenpuffer fuer die grosse Zahl
	private StringBuffer digits = new StringBuffer();
	
	
	
	public BigInteger(int n) {
		if (n < 0) {
			System.out.println("Nur nicht-negative Zahlen erlaubt!");
		} else if (n == 0) {
			digits.insert(0, 0);
		} else {
			digits.append(n);
		}

	}
```


----------



## SlaterB (15. Dez 2010)

gerade den Konstruktor
>  public BigInteger(int n) 
hat Landei doch schon geschrieben

was bei n<0 oder n==0 passieren soll hängt auch davon ab wie du später die Rechen-Methoden baust, für den Anfang musst du das noch nicht supergenau einbauen,
aber sagen wir erstmal das ist gut so, von Reihenfolge im Buffer abgesehen


----------



## Augustiner (15. Dez 2010)

Danke schonmal .....Jetzt weis ich echt nicht mehr weiter irgendetwas fehlt mir 


```
public BigInteger (String s) {
		
		int pString =  s.length();
		
			
		for (int p = digits.length()-1; p >=0; p++){
			getDigit(p);
		}
		
		
	}
```


----------



## SlaterB (15. Dez 2010)

was willst du denn in diesem Konstruktor machen?
reicht nicht einfach 
digits.append(s);
?


----------



## Augustiner (15. Dez 2010)

hast recht hab mich schon wieder von den Kommentaren verwirren lassen


----------



## Augustiner (16. Dez 2010)

Frage ist hier ein wenig richtig oder ist das komplett fürn A****
check das mit dem getDigit , der Rechnung und der Ausgabe nicht....

```
public class BigInteger {
	
	//Zeichenpuffer fuer die grosse Zahl
	private StringBuffer digits = new StringBuffer();
	
	
	
	public BigInteger(int n) {
		if (n < 0) {
			System.out.println("Nur nicht-negative Zahlen erlaubt!");
		} else if (n == 0) {
			digits.insert(0, 0);
		} else {
			digits.append(n);
		}

	}

	public BigInteger(String s) {

		digits.append(s);

	}

	public BigInteger() {

	}

	private int getDigit(int p) {
		if (p >= digits.length())
			return 0;

		return digits.charAt(p) - '0';

	}

	public BigInteger add(BigInteger b) {

		String summe = "";
		int gemerkt = 0;
		for (int p = digits.length() - 1; p >= 0; p++) {

			int zwischenspeicher = p + p + gemerkt;
			summe = zwischenspeicher % 10 + summe;
			gemerkt = zwischenspeicher / 10;

		}
		if (gemerkt != 0)
			summe = gemerkt + summe;

		// Rueckgabewert der Methode
		BigInteger result = new BigInteger();

		result.digits.append(summe);
		// Umkehrung des Buffers, da die Ziffern in umgekehrter Reihenfolge
		// eingetragen werden
		result.digits.reverse();
		return result;
	}

	 /** Ausgabe eines BigIntegers auf der Konsole  */
	public void print() {
	   
	        System.out.println();
	      }

}
```


----------



## SlaterB (16. Dez 2010)

was getDigit() macht, steht dran,
ich hab zwar gesagt dass du allgemein die Kommentare ignorieren kannst, aber wenn du jetzt konkret darüber nachdenkst, dann kannst du ruhig den Methodenkommentar lesen 
was steht da? 'Gibt die Ziffer des BigIntegers an der Stelle p zurueck ', echt nicht zu checken? 
dabei klingt das für mich nach einer normal verständlichen Aussage

------

gleich add() zu implementieren ist schon happig, die Ausgabe einer Zahl oder getDigit() würde ich davor stellen,
teste mit einer Zahl 895, rufe getDigit() für mehrere Indexe auf (welche machen wohl Sinn?), lerne das Programm kennen!
wenn du es schon nicht direkt im Kopf checkst,

danach print() implementieren, gib den StringBuffer direkt aus oder verwende eine Schleife und getDigit(),
muss ja nicht sofort stimmen, teste Reihenfolge, von vorne, von hinten, 
nochmal reverse() (allerdings am Ende der Buffer besser wie vorher), was auch immer machbar erscheint

------

beim add() hast du durchaus schon eine nette Schleife, es fällt aber auf, dass du weder den eigenen Buffer noch den Parameter b benutzt,
wieso addierst du den Index p und nicht die Ziffern an dieser Stelle?

zu checken gibts da eigentlich wenig, aber komplett ohne Denken ("ich muss zwei Ziffern der Zahlen addieren") gehts nun auch nicht..


----------



## Augustiner (16. Dez 2010)

oh ja das is alles sooo logisch , wenn man es nie ordentlich erklärt bekommt checkt man halt nix....
man braucht am Anfang schon ab und zu ne Musterlösung um es zu raffen denke ich 
das ihr alles von begin an drauf hattet ist mir klar....
was solls trotzdem danke .....
ich bin wohl zu blöd


----------



## SlaterB (16. Dez 2010)

du darfst es dir nicht zu einfach machen

es gibt zwei Arten von 'nichts checken',
die erste ist deine a la wirren Code hinschreiben + 'ich kapier gar nix',
wobei dein Code schon recht weit ist mit Übertrag, ziemlich gut,

die andere ist z.B.
'ich muss zwei Zahlen addieren, wie mache ich das auf Papier, aha Ziffer + Ziffer, Übertrag merken,
wie funktioniert das in Java, keiner hat mir Befehle erklärt, wie komme ich an eine Ziffer?, 
wie kann ich strukturiert alle Ziffern durchlaufen (= Schleife)?'

um Java-Kenntnisse gehts gar nicht unbedingt, wenn die fehlen dann kann man ja nachfragen,
viel wichtiger ist die Aufgabe an sich zu begreifen, was letzlich real alles zu tun ist


----------



## Augustiner (16. Dez 2010)

ja und wie binde ich getDigit in die Rechnung ein ?????????


----------



## SlaterB (16. Dez 2010)

aus 
[c]int zwischenspeicher = p + p + gemerkt;[/c]
mit p als Index wird
[c]int zwischenspeicher = getDigit(p) + b.getDigit(p) + gemerkt;[/c]


----------



## Landei (16. Dez 2010)

Die Ziffern sollen (aus gutem Grund) *rückwärts * im StringBuffer gespeichert werden, das tust du nicht.

Und nebenbei: Wozu schreibe ich den Konstruktor, wenn du ihn nicht wenigstens mal anschaust?


----------

