# Potenzieren



## Predator123456 (13. Apr 2011)

würde das funktinoieren?

static int xyhoch (int x,y)   
          this.x = x^2;
          this.y = y ^2;

          return x;
          return y;


----------



## AmunRa (13. Apr 2011)

Du kannst nur einen Wert zurückgeben
es gibt in der Klasse Math eine eigene Methode die potenzieren kann.

diese könntest du einzeln für jede Zahl aufrufen, dann brauchst du deine eigene nicht


----------



## Dekker (13. Apr 2011)

War der Funktionskopf schon gegeben? Wenn ja denke ich du hast die Aufgabe nicht verstanden...
x^y ist sicher nicht x * x und y * y. Was du ausrechnen sollst ist x^y. Falls du nicht mehr weißt wie das mit den Potenzen ist, kannst du dir mal diese Seite beispielsweise nochmal ansehen. Lösen kannst du das ganze am Ende z.b. mit einer for oder while-Schleife.
Ich denke zwar AmunRa hat auch recht, aber so wie ich das sehe, sieht das nach einer Schulaufgabe oder so aus.


----------



## despikyxd (13. Apr 2011)

schon wieder so eine total dumme schulaufgabe von einem genau so dummen info-deppen-lehrer ...
was denkt der wohl wozu es in Java die klasse java.lang.Math gibt -.-' *genau so intiligent wie : wir errechnen mal eben Pi oder programmieren den rest dieser klasse nach ... liebe info-lehrer > SOWAS GEHÖRT IN DEN MATHE-UNTERRICHT !*

public int xpowy(int x, int y) { return (int)Math.pow(x, y); }

und wenn dich dein lehrer fragt was das soll entgegne ihm : was soll der scheiß das ich java.lang.Math nachprogrammieren soll ...


----------



## tfa (13. Apr 2011)

@despikyxd 
Warum soll man überhaupt irgendwas lernen? Gibt doch n Haufen Bücher, wo schon alles drin steht!


----------



## Tomate_Salat (13. Apr 2011)

@despikyxd:
schonmal dran gedacht, dass es vllt weniger um Mathe geht als um z.B. das verwenden einer for-schleife?

@Predator123456:
Hier geht es eigentl. um Sichtbarkeiten und nicht um deine schulischen Probleme. Mach selber ein Thema auf oder besser: frage einen Mod ob er deinen+darauf folgende Beiträge von dem Thema hier in ein separates trennt.


----------



## Predator123456 (13. Apr 2011)

Habe die Aufgabe aus einem Lehrbuch, die wollen das man in jede Zeile auskomentiert hab aber die Lösung nicht mehr weiß das keiner ?


----------



## maki (13. Apr 2011)

@Predator123456

Bitte beim nächsten mal ein bisschen nachdenken und nicht wild in irgendeinem thread dein Problem posten, ein passender Titel anstatt "Hilfe!!! Dringend !!! BlaBla" auch erwünscht.


----------



## Tomate_Salat (13. Apr 2011)

Predator123456 hat gesagt.:


> Habe die Aufgabe aus einem Lehrbuch, die wollen das man in jede Zeile auskomentiert hab aber die Lösung nicht mehr weiß das keiner ?



Lösungen bekommst du hier keine, wir helfen dir aber gerne dabei. Das dein Vorschlag nicht funktioniert sollte klar sein (mal abgesehen von den 2 returns)


----------



## Firephoenix (13. Apr 2011)

Hi,
mal zum Problem:
Du sollst eine Methode schreiben die 2 Zahlen konsumiert und deren Potenz bildet.

wenn du eine Zahl x hast und eine Zahl y, dann ist die Potenz davon nichts anderes als 
x*x*x*x*x*...*x*x und das machst du genau y-mal.

Deine Funktion kriegt also beide Zahlen und du multiplizierst die erste Zahl immer mit sich selbst.
Das Ergebnis davon wird dann zurückgegeben.

Hier scheint ein absolutes Verständnisproblem vorzuliegen, einmal bei Funktionen, und einmal bei den Mathe-Operationen.

Und @despikyxd
Warum programmiert man etwas nach? Um zu verstehen wie es funktioniert und als Übung.
Klar, wenn ich ein 3D Spiel basteln will baue ich mir kein 3D Framework zusammen wenn es genug gibt, aber um zu verstehen wie Grafik funktioniert muss man trotzdem erstmal selber einfache Sachen nachbauen.
Genau aus dem Grund findest du auch oft genug Übungsaufgaben wie: Schreiben sie einen eigenen Stack, eine eigene Liste, eine eigene Sortierfunktion, einen eigenen Baum, oder eine eigene Implementierung einer Formel.
Lehrer die solche Aufgaben stellen sind meiner Meinung nach nicht Dumm, sondern didaktisch brauchbar.
Unbrauchbar dagegen sind dagegen z.B. solche Kommentare oder Lehrer die Anfängern irgend ein eigenes Framework hinknallen nach dem Motto "da draufdrücken, das geht dann schon irgendwie, macht mal". Da gab es hier im Forum auch schon einige Horrorthreads wo Leuten dadurch massiv Grundlagen vorenthalten wurden.
Gruß


----------



## Predator123456 (13. Apr 2011)

Habe vor das morgen mal meinem Lehrer zu zeigen, wir sind zwar mit dem Stoff noch nicht soweit aber ich versuche schon immer etwas flotter den Stoff zu verarbeiten  aber mir fehlen wohl echt noch die Basics :/


----------



## Firephoenix (14. Apr 2011)

Hi,
dann viel Erfolg beim Basics lernen,
da der Thread zwar erledigt markiert ist, aber das Problem an sich noch nicht gelöst wurde möchte ich wenigstens mal eine komplett Durchkommentierte version anbieten:

```
public static void main(String[] args) {
		/*
		 * das Programm startet immer in der Main-Methode, durch static kann
		 * auf die Methode zugegriffen werden ohne eine Instanz der Klasse zu erstellen.
		 * Beispiele dafür sind z.B. die Math - Methoden.
		 * Du kannst Methoden wie die Wurzel (Math.sqrt()) einfach aufrufen ohne vorher
		 * sowas zu machen Math matheObjekt = new Math();
		 * und dann matheObjekt.sqrt().
		 * 
		 * In der main Methode mit diesem Kopf wie hier startet immer das Java-Programm.
		 */
		
		//Wir Nehmen uns erstmal zwei zahlen
		//Am Anfang ist das einfacher als Konsoleninputs, da man schnell an 
		//Testwerte kommt ohne sich um Eingaben zu kümmern.
		int basis = 2;
		int exponent = 4;
		
		//Hier speichern wir den Rückgabewert der Funktion (mehr dazu unten)
		int xyz = potenziere(basis,exponent);
		
		//Das hier ist der einfache Ausgabebefehl (bekannt aus z.B. Hello-World)
		//für die Java-Konsole.
		System.out.println(xyz);
		//In unserem Beispiel wäre die Ausgabe 16 was (2*2*2*2) = 16 entspricht.
		
		//Hier ein paar weitere Beispiele, etwas kürzer gefasst (wir sparen uns das zwischenspeichern
		//vor der Ausgabe und rufen die funktion direkt mit werten auf)
		System.out.println(potenziere(2,2));
		System.out.println(potenziere(5,2));
		System.out.println(potenziere(3,3));
		System.out.println(potenziere(0,0));
		System.out.println(potenziere(4,0));
	}
	
	/*Das wird jetzt die Methode die aufgerufen wird wenn du die Potenz berechnen willst.
	 * Die Methode ist public (Sichtbarkeit bitte selbst nachschlagen), static (siehe oben)
	 * Int bedeutet,dass das Ergebnis der Methode ein int ist.
	 * int b und int e sind parameter die ich der Methode beim Aufruf übergeben kann
	 * (also Platzhalter), zum Aufruf siehe Oben.
	 */
	public static int potenziere(int b, int e){
		//Am Anfang der Funktion fängt man in der Regel spezialfälle ab.
		//Wenn der exponent 0 ist gibt die Potenz immer 1 (sollte ich mich
		//irren Asche auf mein von Unimathe geplagtes Haupt :D)
		if(e == 0){
			//Wenn e gleich 0 ist (doppeltes =) geben wir 1 weiter
			//Ansonsten überspringen wir den Teil
			return 1;
		}
		//wir kopieren uns zuerst mal b,
		//damit haben wir es leichter uns b und das Ergebnis zu merken
		int result = b;
		//Hier kommt die Schleife zum Rechnen ins Spiel.
		//Als Text übersetzt heißt die Stelle hier:
		//Fange mit einem Wert int i = 1 an, solange i kleiner als e ist machst du alles
		//Was in den {} steht und erhöhst dannach i um 1. Dann fängst du wieder von vorne an.
		//Angenommen e wäre 2. dann müsstest du b*b rechnen.
		//i ist erst 1, 1 ist kleiner als 2, also wird result (das ja schon b enthält) mal b
		//genommen und in result steht b*b. Jetzt wird i erhöht und ist 2.
		//e war aber auch 2, also stimmt die Schleifenbedingung 2 < 2 nicht mehr, die Schleife wird verlassen
		for(int i = 1; i < e; i++){
			result = result*b; //alternativschreibweise: result *= b;
		}
		//Am Ende geben wir den in result gespeicherten Wert zurück
		return result;
	}
```
Gruß
Edit: sollten Fehler drin sein sammel ich sie gerne raus wenn ich wach bin.


----------



## Landei (14. Apr 2011)

Eine performante Version:


```
public static long pow(int x, int e) {
        if (e < 0) throw new IllegalArgumentException();
        long result = 1;
        while(e > 0) {
            if (e % 2 == 1) result *= x;
            e /= 2;
            if(e > 0) x = x*x;
        }
        return result;
    }
```


----------



## Andi_CH (14. Apr 2011)

Ist die performanter weil sie weniger Kommentar enthält? :lol:
Ob while oder for .... na ja


----------



## Landei (14. Apr 2011)

Ist dir der Unterschied _wirklich _nicht klar? Dann solltest du nicht lachen, sondern lieber etwas lernen: Binäre Exponentiation ? Wikipedia

Beispielsweise berechnet man x^6 nicht als x*x*x*x*x*x, sondern ((x²)*x)², braucht also nur 3 Multiplikationen anstatt 5. Für große Exponenten fällt der Unterschied noch deutlicher aus.


----------



## Andi_CH (14. Apr 2011)

Schreib in C 6 "*" hin und du wirst deutlich schneller fertig sein als mit einem beliebigen Algorithums in Java - den lezten Rest an Performance in C rauszuholen ist etwa wie wenn du deinen Golf tunst um gegen einen BMW535 anzutreten ...


----------



## Firephoenix (14. Apr 2011)

Andi_CH hat gesagt.:


> Schreib in C 6 "*" hin und du wirst deutlich schneller fertig sein als mit einem beliebigen Algorithums in Java - den lezten Rest an Performance in C rauszuholen ist etwa wie wenn du deinen Golf tunst um gegen einen BMW535 anzutreten ...



Wie hängt man an einen falschen Kommentar noch eine Stammtischaussage die genauso inkorrekt ist?

Zitat übrigens aus Wiki zu dem Algo:


> Bei der einfachen und langsamen Potenzierung von xc werden (c − 1) Multiplikationen benötigt. Beim „Square & Multiply“ wird die Schleife lediglich log2(c)-mal durchlaufen (log2(c) entspricht hierbei ungefähr der Länge der Zahl c in der Binärdarstellung). In jedem Schleifendurchlauf kommt es zu einer Quadrierung (wobei die erste Quadrierung vernachlässigt werden kann) und eventuell einer Multiplikation. Asymptotisch werden O(log(c)) Operationen (eventuell Langzahloperationen) benötigt, wogegen O(c) Operationen bei der einfachen Potenzierung zu Buche schlagen. O bezeichnet eine asymptotische obere Schranke für das Laufzeitverhalten des Algorithmus. Wie man leicht einsieht, ist das „Square-&-Multiply“-Verfahren sehr viel effizienter als das einfache Verfahren. Dieser verringerte Anspruch an die Rechenleistung ist bei großen Basen und Exponenten enorm.



Genau das hat dir Landei auch versucht zu erklären.
Und du kannst Laufzeitunterschiede in der O-Notation eben nicht mit Faktoren wie Sprachenlaufzeit verändern, da die O-Notation solche Faktoren ausblendet.
Damit können wir uns hier auch gleich die Java im Vergleich zu C Debatte sparen, aber zu der Aussage "Java ist langsam" wirst du selbst auch genug aktuelle Artikel finden die auch mal das Gegenteil verraten 

Gruß


----------



## Crian (15. Apr 2011)

Wenn man zu Übungszwecken Basisfunktionalitäten nachprogrammiert, dann macht Optimierung vermutlich wenig Sinn. Wobei der Algorithmus natürlich "schlauer" ist. Ich hoffe mal, dass die Math-Bibliothek da ebenfalls schlaue Wege wählt.


----------



## Logaff (21. Apr 2011)

die frage ist: warum?

weil ich es kann ist nicht die angebrachte begründung und ich glaub man hat soviel verständniss dafür was eigentlich passiert beim potenzieren das man es nicht algorithmisch durchdringen muss, wenn es nich gerade irg wo eine blöde aufgabe für irgend was ist.

kleine frage nebenbei....was macht der algo wenn man gebrochene Exponenten( wurzel(x,2) = x^(1/2)) eingibt (bezieht sich jetzt auf Math.pow(x,0.5)


----------



## Landei (21. Apr 2011)

Das wird über geeignete Reihenentwicklung angenährt. Eine Methode wäre über Logarithmen (ob das bei Math.pow wirklich so gemacht wird, kann ich nicht sagen):

12^1.23 = exp(1.23 * ln(12))

Für beide Funktionen [c]exp[/c] und [c]ln[/c] gibt es gut konvergierende Reihen.


----------

