# Wurzel ziehen



## Kaiser206 (27. April 2006)

Hallo,
weiß jemand wei man eine funktion schreibt die die Wurzel aus einer Zahl ziehen kann?
Ich habe folgendes gemacht:


```
input=7;

  double x=1;
  double y=input;
  double z=1;

  for(int i=1;i<10;i++)
  {
    for(;input>x*x;x=x+z);
    for(;input<y*y;y=y-z);
    z=z/10;
  }
```

Dieses Programm zeigt aber nur x=2,y=3 an. So wie es da steht sollte es aber genauerf berechnen. Kann mir jemand sagen so mein Fehler ist?
PS: Ich muss die Funktion selber schreiben. Die mitgeleiferten kann/darf ich also nicht einsetzen!


----------



## Messiahs_128 (27. April 2006)

Hi,
wenn ich mich nicht täusche ist das quadratwurzel nach heron?

siehe hier
http://www.schulmodell.de/mathe/lexikon/heron.php

das steht die funktionsweise erlärt. Na dann viel spaß


----------



## Martin Schroeder (27. April 2006)

Versuchs mit dem Intervallhalbierungsverfahren.


----------



## Kaiser206 (27. April 2006)

Aber was genau war jetzt an meinem Beispiel falsch? Im grunde funktionierte alles einwandfrei, nur das z nach der initialisierung offenbar nicht verändert wurde... Und was hat die Quadratwurzel damit zutun?

Mit dem Link komme ich nur auf eine Seite wo ich das berechnen kann, aber nicht dahin wo man die einzelnen Schritte erklärt...


----------



## Messiahs_128 (27. April 2006)

Über der berechnung steht wie man das lösst wenn nicht hasste hier nen anderen link
http://www.gefilde.de/ashome/vorlesungen/algorithmen/algo_abschn42/algo_abschn42.html

edit 1:
http://www.mathepower.com/xsys/lexikon/show/Wurzelziehen-verst%E4ndlich.html


----------



## Matthias Reitinger (27. April 2006)

Kaiser206 hat gesagt.:
			
		

> Aber was genau war jetzt an meinem Beispiel falsch? Im grunde funktionierte alles einwandfrei, nur das z nach der initialisierung offenbar nicht verändert wurde... Und was hat die Quadratwurzel damit zutun?


Doch, z wurde schon verändert. Nur werden die Schleifenkörper der beiden for-Schleifen nur genau einmal durchlaufen, und zwar beim ersten Durchgang der äußeren Schleife. Wenn input nach dem ersten Durchlauf schon größer als x*x ist, dann wird beim zweiten Durchlauf überhaupt nicht mehr in den Schleifenkörper gesprungen. Abilfe würde z.B. folgendes schaffen:

```
for (int i = 1; i < 10; ++i) {
	while (input > x*x) x += z;
	x -= z;
	while (input < y*y) y -= z;
	y += z;
	z /= 10;
}
```
Ich war mal so frei und hab die verkürzenden Zuweisungoperatoren verwendet und die initialisierungslosen for- in leichter lesbare while-Schleifen verwandelt.

Ich würde aber dennoch das Babylonische Wurzelziehen (auch bekannt als Heron-Methode) empfehlen, da es im Vergleich zu deinem Algorithmus um einiges schneller auf gleich genaue Ergebnisse kommen sollte.


----------



## Flegmon (28. April 2006)

Matthias Reitinger hat gesagt.:
			
		

> for (int i = 1; i < 10; ++i) {
> while (input > x*x) x += z;
> x -= z;
> while (input < y*y) y -= z;
> ...



Das rot Markierte fürt zu einem Fehler, wenn die eingabe 0 ist. Außerdem ist es ja sinnlos, die Wurzel 2 mal zu berechnen.


----------



## Kaiser206 (28. April 2006)

Das Wurzel ziehen funktioniert jetzt einigermaßen. Aber ich hätte da noch eine Frage:

Mit den double variablen x,y kann ich nur werte mit begrenzter Nachkommastellen speichern. Gibt es eine Möglichkeit das z.B 100 Nachkommastellen ermittelt werden?

PS: Das Heronverfahren scheint wirklich besser zu sein:

 int wurzelaus = 16;
 double x=1;
 double y=wurzelaus;
 for(int i=1;i<1000;i++)
 {
   x=(x+y)/2;
   y=wurzelaus/x;
 }


----------



## Matthias Reitinger (28. April 2006)

Flegmon hat gesagt.:
			
		

> Außerdem ist es ja sinnlos, die Wurzel 2 mal zu berechnen.


Das hat mich zunächst auch etwas stutzig gemacht – ich ging dann aber davon aus, dass der OP sich dem Wert der Wurzel von beiden Seiten nähern und dann den Mittelwert verwenden wollte. Das ließe sich aber wohl auch effizienter lösen.


----------

