Wurzelziehen mittels Intervallschachtelung (Schleifen)
Ein Möglichkeit manuell Quadratwurzeln aus einer Zahl zu ziehen ist die Intervallschachtelung.
Schreibe eine Funktion, die die oberen und unteren Grenzwerte ausgibt bis eine Näherung an die tatsächliche Wurzel eingetreten ist. (Genauikeit: 5 Stellen hinter dem Komma)
Vorgehen:
Finde zwei Nachbarzahlen (größer und kleiner), die ganzzahlige Quadratwurzel haben. Dies sind die oberen und unteren Grenzwerte.
Annäherung an die Wurzel mittels Intervallschachtelung:
Das Quadrat des Mittelwerts der Summe des oberen und unteren Grenzwertes ergibt einen Wert k, der größer oder kleiner als x ist.
Ist der Wert k größer x, so ist er der Mittelwert der neue obere Grenzwert
Ist der Wert k kleiner x, so ist er der Mittelwert der neue untere Grenzwert.
Klingt kompliziert, ist aber hier deutlich anschaulicher erklärt.
https://www.matheretter.de/wiki/wurzelwert-intervallschachtelung-mittelwertbildung
0 Kommentare
5 Lösung(en)
# frozen_string_literal: false
def my_sqrt(x)
r_control = Math.sqrt(x)
limit = 0.000001
puts format('Die gesuchte Wurzel ist %<r_control>0.20f.', r_control: r_control)
a = 0
a += 1 while (a**2) < x
b = a - 1
puts format('Start mit Grenzen %<a>d und %<b>d.', a: a, b: b)
steps = 0
while true
steps += 1
d = (a + b).fdiv(2)
diff = (d - r_control).abs
puts format('Schritt %<steps>d: Abweichung ist %<diff>0.20f.', steps: steps, diff: diff)
# break if diff <= limit # Abbrechen, wenn Abweichung kleiner als Limit
s = format('%20f', d) # auskommentieren fuer anderes Limit
nil while s.chomp!('0') # auskommentieren fuer anderes Limit
break if s.split('.').last.size > 5 # Abbrechen, wenn fuenf Nachkommastellen erreicht sind.
a = (d**2) > x ? d : a
b = (d**2) < x ? d : b
puts format('Nach Schritt %<steps>d: a -> %<a>0.20f ~ b -> %<b>0.20f', steps: steps, a: a, b: b)
end
puts format('Gesucht war %<r_control>0.20f. Fertig mit Grenzen %<a>0.20f und %<b>0.20f,
Loesung ist %<d>0.20f mit einer Abweichung von %<diff>0.20f.',
r_control: r_control, a: a, b: b, d: d, diff: diff)
end
puts 'Welche Zahl soll gewurzelt werden?'
x = gets.chomp
x = Integer(x)
# x = 44 # Testparameter
my_sqrt(x)
# Die Genauigkeitsangabe ist irgendwie merkwuerdig und umstaendlich zu loesen, aber sinnig, wenn man nur mit der
# selbstgebauten Wurzelfunktion arbeiten soll. Kann durch Umkommentieren in den Zeilen 22 bis 27
# zu einer wertbasierten Annaeherung umgeschaltet werden, je nachdem, was einem sinnvoller vorkommt.
Lösung von: Ich Bins (tubs)
// NET 6.x; C# 10.x
using static System.Math;
const double n = 7.0; // Zahl
const int p = 5; // Genauigkeit
var (l, u) = SqrtNestedInterval(n, p + 1);
Console.WriteLine($"Untergrenze:\t{l}\nObergrenze:\t{u}\n");
Console.WriteLine($"Wurzel {n}:\t{Sqrt(n)}");
static (double l, double u) SqrtNestedInterval(double n, int p)
{
var l = 0.0;
var u = 0.0;
for (var i = 0; i < p; i++)
{
while (Pow(l, 2) < n)
l += Pow(0.1, i);
u = l;
l -= Pow(0.1, i);
}
return (Round(l, p), Round(u, p));
}
Lösung von: Jens Kelm (@JKooP)
// C++ 17
#include <iostream>
#include <tuple>
#include <iomanip>
std::tuple<double, double> sqrt_nested_interval(double n, int p) {
auto l{ 0.0 };
auto u{ 0.0 };
for (auto i{ 0 }; i < p; i++)
{
while (pow(l, 2) < n)
l += pow(0.1, i);
u = l;
l -= pow(0.1, i);
}
return std::make_tuple(l, u);
}
int main() {
const double n = 7.0; // Zahl
const int p = 5; // Genauigkeit
auto sni{ sqrt_nested_interval(n, p + 1) };
std::cout << std::fixed << std::setprecision(p);
std::cout << "Untergrenze:\t" << std::get<0>(sni) << "\nObergrenze:\t" << std::get<1>(sni) << std::endl;
std::cout << std::defaultfloat << "Wurzel (" << n << "):\t" << std::setprecision(10) << sqrt(n) << std::endl;
}
Lösung von: Jens Kelm (@JKooP)
// Achtung: F#
let sqrtNestedInterval n p =
let mutable l = 0.0
let mutable u = 0.0
for i in 0 .. p do
while l ** 2 < n do
l <- l + 0.1 ** i
u <- l
l <- l - 0.1 ** i
(l, u)
let n = 7.0 // number
let p = 5 // precision
let (l, u) = sqrtNestedInterval n p
printfn "Untergrenze: %A, Obergrenze: %A" l u
Lösung von: Jens Kelm (@JKooP)
' VBA
Type Interval
floor As Double
ceiling As Double
End Type
Public Function SqrtNestedInterval(value As Double, precision As Integer) As Interval
Set wsf_ = WorksheetFunction
Dim interval_ As Interval
Dim floor_ As Double, ceiling_ As Double
Dim i As Integer
For i = 0 To precision
Do While wsf_.Power(floor_, 2) < value
floor_ = floor_ + wsf_.Power(0.1, i)
Loop
ceiling_ = floor_
floor_ = floor_ - wsf_.Power(0.1, i)
Next i
interval_.floor = floor_
interval_.ceiling = ceiling_
SqrtNestedInterval = interval_
End Function
Sub Main()
Dim interval_ As Interval
interval_ = SqrtNestedInterval(7, 5)
Debug.Print "Untergrenze: " & interval_.floor
Debug.Print "Obergrenze: " & interval_.ceiling
Debug.Print "Wurzel: " & Sqr(7)
End Sub
Lösung von: Jens Kelm (@JKooP)
Verifikation/Checksumme:
Zahl deren Wurzel berechnet werden soll eingeben: 44
Wert größer: 6.0
Wert kleiner: 7.0
Mittelwert zum Quadrat ist kleiner als 44
Obere Grenze ist daher 7.0
Untere Grenze ist daher6.5
angenähertes Ergebnis ist 6.5
-----------
Mittelwert 6.75 zum Quadrat ist größer als 44
Obere Grenze ist daher 6.75
Untere Grenze ist daher 6.5
angenähertes Ergebnis ist 6.75
-----------
Mittelwert zum Quadrat ist kleiner als 44
Obere Grenze ist daher 6.75
Untere Grenze ist daher6.625
angenähertes Ergebnis ist 6.625
-----------
Mittelwert 6.6875 zum Quadrat ist größer als 44
Obere Grenze ist daher 6.6875
Untere Grenze ist daher 6.625
angenähertes Ergebnis ist 6.6875
-----------
Mittelwert 6.65625 zum Quadrat ist größer als 44
Obere Grenze ist daher 6.65625
Untere Grenze ist daher 6.625
angenähertes Ergebnis ist 6.65625
-----------
Mittelwert 6.640625 zum Quadrat ist größer als 44
Obere Grenze ist daher 6.640625
Untere Grenze ist daher 6.625
angenähertes Ergebnis ist 6.640625
...
Aktionen
Neue Lösung hinzufügen
Bewertung
Durchschnittliche Bewertung: