Frage: Quadratwurzel mit annährungsvariable

11/13/2018 15:10 LenoxArt's#1
Hallo Leute,

bin in meinem Studium noch recht frisch in Java drin. Bisher konnte ich alle Aufgaben lösen aber folgende zerstört irgendwie mein Hirn ^^.


Code:
Schreiben Sie ein Programm, welches die Quadratwurzel einer positiven Fließkommazahl näherungs-
weise bestimmt. In Ihrem Programm soll die Genauigkeit, mit der Sie das Ergebnis ermitteln wollen, 
variabel sein und in einer Variablen (z.B. 
double precision = 0.1;
) 
angegeben werden.
Ich versteh nicht genau wie ich die Aufgaben angehen soll.
In einer vorigen Aufgabe musste man feststellen ob eine angebene Zahl eine Quadratwurzel ist oder nicht. Das war recht easy mit der Math.sqrt() funktion und anschließender multiplikation der errechneten Wurzel..

Hoffe ihr könnt mir hier vielleicht etwas auf die Sprünge helfen :/

Hier bspw. wie die Aufgabe der vorigen Woche gelöst wurde von mir.
Code:
                // Einsen in Binär
		System.out.println(Integer.toBinaryString(x));
		System.out.println("Es sind "+Integer.bitCount(x)+" Einsen in der Binärdarstellung vorhanden");
		
		// Quadratzahl testen
		quadz = (int) Math.sqrt(x);
		tmpQ = quadz*quadz;
		if(tmpQ == x) {
			System.out.println("Die Zahl "+x+" ist eine Quadratzahl");
			System.out.println("Quadratwurzel aus "+x+" ist :"+ quadz);
		}
		else {
			System.out.println("Die Zahl "+x+" ist keine Quadratzahl");
		}
		
		// Kubikzahl testen
		kubik = Math.cbrt(x);
		tmpK = kubik*kubik*kubik;
		if(tmpK == x) {
			System.out.println("Die Zahl "+x+" ist eine Kubikzahl");
			System.out.println("Kubikwurzel aus "+x+" ist :"+ kubik);
		}
		else {
			System.out.println("Die Zahl "+x+" ist keine Kubikzahl");
		}
11/13/2018 17:35 florian0#2
Im Gegensatz zu einigen anderen mathematischen Problemen, lässt sich die Quadratwurzel einer Zahl nicht mit einem einfachen Rechenschritt bestimmen. In der Tat sind alle Implementationen der Funktion Sqrt() nur Näherungsverfahren, manchmal auch unterstützt durch Tabellen damit man nicht zu viel rechnen muss.

Du könntest zum Beispiel ein "eigenes" erfinden. Wie wäre es mit Stumpf ausprobieren. Fang beim Wert der Genauigkeit an und zähle solange in Schritten der Genauigkeit hoch, bis die Quadrierung der Zahl entweder genau der gesuchten Zahl entspricht, oder sich wieder davon entfernt.
Das dieses Verfahren weniger Optimal ist, kannst du dir sicher denken. Schließlich ist die Ausführungszeit Maßgeblich von der effektiven Größe der Zahl und der verwendeten Genauigkeit abhängig. Nichtsdesto trotz ist es ein Näherungsverfahren und da in der Aufgabenstellung nicht explizit gesagt ist, dass es gut sein müss, würde ich behaupten das gilt ;D. Falls das zu meiner Tutorenzeit einer meiner Studis hinbekommen hätte, wäre ich jedenfalls glücklich gewesen ;D.

Ein wenig Klüger ist z.B. das Heron-Verfahren.
> https://de.wikipedia.org/wiki/Heron-Verfahren
Hier kann in nur wenigen Schritten eine hohe Genauigkeit erzielt werden.

Falls du Angst vor Mathe hast, schau dir am Besten nur an, wie das Beispiel funktioniert. Das Ganze ist eine Iterationsgleichung, du brauchst also eine Schleife oder eine Rekursion dafür.
Die Genauigkeit an der Stelle beschreibt die "Änderung von X pro Iteration".

Nachtrag: Just for the lulz hab ich das mal in meiner Lieblingssoftware Matlab (:reeee:) gebaut, weil man da so schön Zeit messen kann.
11/13/2018 21:28 LenoxArt's#3
Danke dir, tatsächlich steht in der Überschrift der Aufgabe auch drin, dass es mit Schleifen gelöst werden soll.
Was mich an der Aufgabe nur verwundert, dass diese die Komplexität aller vorigen Aufgaben (inklusive Bonusaufgaben) sowie den Rest des Aufgabenblattes übertrifft :D
Ich schau mir dieses Heron verfahren mal an :)

Quote:
Originally Posted by florian0 View Post
Im Gegensatz zu einigen anderen mathematischen Problemen, lässt sich die Quadratwurzel einer Zahl nicht mit einem einfachen Rechenschritt bestimmen. In der Tat sind alle Implementationen der Funktion Sqrt() nur Näherungsverfahren, manchmal auch unterstützt durch Tabellen damit man nicht zu viel rechnen muss.

Du könntest zum Beispiel ein "eigenes" erfinden. Wie wäre es mit Stumpf ausprobieren. Fang beim Wert der Genauigkeit an und zähle solange in Schritten der Genauigkeit hoch, bis die Quadrierung der Zahl entweder genau der gesuchten Zahl entspricht, oder sich wieder davon entfernt.
Das dieses Verfahren weniger Optimal ist, kannst du dir sicher denken. Schließlich ist die Ausführungszeit Maßgeblich von der effektiven Größe der Zahl und der verwendeten Genauigkeit abhängig. Nichtsdesto trotz ist es ein Näherungsverfahren und da in der Aufgabenstellung nicht explizit gesagt ist, dass es gut sein müss, würde ich behaupten das gilt ;D. Falls das zu meiner Tutorenzeit einer meiner Studis hinbekommen hätte, wäre ich jedenfalls glücklich gewesen ;D.

Ein wenig Klüger ist z.B. das Heron-Verfahren.
> https://de.wikipedia.org/wiki/Heron-Verfahren
Hier kann in nur wenigen Schritten eine hohe Genauigkeit erzielt werden.

Falls du Angst vor Mathe hast, schau dir am Besten nur an, wie das Beispiel funktioniert. Das Ganze ist eine Iterationsgleichung, du brauchst also eine Schleife oder eine Rekursion dafür.
Die Genauigkeit an der Stelle beschreibt die "Änderung von X pro Iteration".

Nachtrag: Just for the lulz hab ich das mal in meiner Lieblingssoftware Matlab (:reeee:) gebaut, weil man da so schön Zeit messen kann.

Habs jetzt so gelöst, danke dir !:)
Code:
import java.util.*;

public class Quadratwurzel {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		//Initialisierung
		
		Scanner einlesen = new Scanner(System.in);
		double ausgabe, zahl, precision;
		
		// Einlesen
		
		System.out.println("Bitte geben Sie eine Zahl ein: ");
		zahl = einlesen.nextDouble();
		System.out.println("Bitte geben Sie die Präzision ein: ");
		precision = einlesen.nextDouble();
		
		// Ausgeben
		
		ausgabe = square(zahl, precision);
		System.out.println(ausgabe);

	}
	
	public static double square (double x, double precision) {
		double a = x;
		double b = precision;
		
		for(int i=1; i<= 100; i++) {
			b = (a+b)/2;
			a = x/b;
			System.out.println(a);
		}
		
		return a;
		
		
	}

}