Do Schleife: Exit Do

  • VB.NET

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von VBWorld.

    Do Schleife: Exit Do

    Hallo,
    ich schreibe gerade an einem Programm, bei dem Quadratwurzeln bestimmt werden: Also der User gibt den Radikanten an und die Unterste und Oberste Zahl, z.B.: Radikant: 13, Unten: 3, Oben: 4. Dann wird der Mittelwert von Unten und Oben bestimmt: 3,5, diese Zahl wird jetzt mit sich selber multipliziert: 12,25. 12,25 ist kleiner als der Radikant, also unser neues Unten. Nun fängt der Spaß von vorne an ......

    Diese ganze Prozedur habe ich in eine Endlosschleife gemacht, wenn der Mittelwert² jetzt gleich dem Radikanten ist soll die Schleife gestoppt werden mit Exit Do, das klappt leider nicht ......... Die Schleife läuft weiter

    MFG
    MFG VBWorld
    Mathe ist für alle die, die nicht mit dem Taschenrechner umgehen können :D
    Mein Code:

    VB.NET-Quellcode

    1. Do While True
    2. If Mitte2 < rak Then
    3. oben = CDbl(ListView2.Items(ListView2.Items.Count - 1).Text)
    4. unten = CDbl(ListView2.Items(ListView2.Items.Count - 1).SubItems(2).Text)
    5. Diff = oben - unten
    6. Mitte = Diff / 2 + unten
    7. Mitte2 = Mitte * Mitte
    8. With ListView2.Items.Add(oben.ToString)
    9. .SubItems.Add(unten.ToString)
    10. .SubItems.Add(Mitte.ToString)
    11. .SubItems.Add(Mitte2.ToString)
    12. .SubItems.Add(Diff.ToString)
    13. End With
    14. If Mitte2 = rak Then
    15. Exit Do
    16. End If
    17. Else
    18. oben = CDbl(ListView2.Items(ListView2.Items.Count - 1).SubItems(2).Text)
    19. unten = CDbl(ListView2.Items(ListView2.Items.Count - 1).SubItems(1).Text)
    20. Diff = oben - unten
    21. Mitte = Diff / 2 + unten
    22. Mitte2 = Mitte * Mitte
    23. With ListView2.Items.Add(oben.ToString)
    24. .SubItems.Add(unten.ToString)
    25. .SubItems.Add(Mitte.ToString)
    26. .SubItems.Add(Mitte2.ToString)
    27. .SubItems.Add(Diff.ToString)
    28. End With
    29. If Mitte2 = rak Then
    30. Exit Do
    31. End If
    32. End If
    33. Loop
    MFG VBWorld
    Mathe ist für alle die, die nicht mit dem Taschenrechner umgehen können :D
    Hi
    hab' mal schnell einen allgemeingültigen Code für sowas programmiert:

    VB.NET-Quellcode

    1. Shared Function SqrtInt(value As Integer) As Integer
    2. If value < 0 Then Throw New ArgumentException("Positive value expected.")
    3. Return EvaluateByInverse(value, 0, (value + 1) \ 2, Function(l, r) l + (r - l) \ 2, Function(v) v * v, Function(l, r) l.CompareTo(r))
    4. End Function
    5. Shared Function EvaluateByInverse(Of TResult, TValue)(
    6. value As TValue,
    7. lower As TResult,
    8. upper As TResult,
    9. averageFunction As Func(Of TResult, TResult, TResult),
    10. inverseFunction As Func(Of TResult, TValue),
    11. comparison As Comparison(Of TValue)) As TResult
    12.         If averageFunction Is Nothing Then Throw New ArgumentNullException("averageFunction")
    13.         If inverseFunction Is Nothing Then Throw New ArgumentNullException("inverseFunction")
    14.         If comparison Is Nothing Then Throw New ArgumentNullException("comparison")
    15. Dim prev As TValue
    16. Dim avg As TResult = averageFunction(lower, upper)
    17. Dim invavg As TValue = inverseFunction(avg)
    18. Dim cmp As Integer = comparison(invavg, value)
    19. Do
    20. If cmp < 0 Then ' f^-1(average(l, r)) < value
    21. lower = avg
    22. ElseIf cmp > 0 Then
    23. upper = avg
    24. Else
    25. Return avg
    26. End If
    27. prev = invavg
    28. avg = averageFunction(lower, upper)
    29. invavg = inverseFunction(avg)
    30. cmp = comparison(invavg, value) * Math.Abs(comparison(invavg, prev))
    31. Loop
    32. End Function

    Für sowas arbeitet man nicht direkt auf der GUI und man würde in deinem Fall ein DataGridView verwenden.

    value ist der Parameter, der in die Funktion eingesetzt werden soll
    lower ist die untere Schranke, die sollte möglichst so gewählt werden, dass sie möglichst nah unter dem Ergebnis liegt, aber effizient berechnet werden kann (d.h. möglichst in O(1))
    upper ist die obere Schranke, die sollte möglichst so gewählt werden, dass sie möglichst nah über dem Ergebnis liegt, aber effizient berechnet werden kann (d.h. möglichst in O(1))
    averageFunction stellt die Funktion bereit, die für den Durchschnitt verwendet werden soll (als Delegat zur Abstraktion), wie bei Integer z.B. eben (x + y)/2 = x + (y - x)/2 (zur Überlaufprävention)
    inverseFunction ist die Umkehrfunktion, die die Funktion bestimmt. Für die muss eben strenge Monotonie im durch [lower, upper] bestimmten Intervall gelten (bzw. für die Werte, die untersucht werden, dazwischen ist's ja egal).
    comparison vergleicht dann eben den bisher ermittelten Wert mit dem der Inversen.

    Die Funktion bricht ab, wenn der Wert exakt bestimmt wurde oder keine Änderung am Wert herbeigeführt wurde (wird durch den Faktor Math.Abs(comparison(invavg, prev)) erzwungen, wenn das unerwünscht ist, einfach weglassen).

    Gruß
    ~blaze~

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „~blaze~“ ()

    @~blaze~

    Danke :)

    Aber ich würde trotzdem gerne wissen warum mein Code nicht funktinoniert ....

    Für sowas arbeitet man nicht direkt auf der GUI


    Doch jeder soll nämlcih die einzelnen Schritte sehen können. Wir haben das heute in der Schule mit Excel gemacht, und deswegen wollte ich es nochmal mit VB machen
    MFG VBWorld
    Mathe ist für alle die, die nicht mit dem Taschenrechner umgehen können :D

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VBWorld“ ()

    Stimmen die Werte denn? Ggf. wird's ja durch die Ungenauigkeit von Double hervorgerufen? Es ist einfach nur hässlicher "Gurkencode" (sorry, wenn ich's so unverblümt ausdrück, aber es ist so). Man sitzt davor, nach ein paar Minuten wird dann mal erkennbar, was gemeint ist, obwohl der Code prinzipiell einfach nur trivial wäre, würde man ihn in eine sinnvolle Architektur gießen.

    Wenn du ein Feedback willst, mach's über Delegaten oder Events. Z.B.:

    VB.NET-Quellcode

    1. Public Delegate Sub EvaluationFeedback(Of TResult, TValue)(left As TResult, right As TResult, average As TResult, value As TValue)
    2. Shared Function SqrtInt(value As Integer, feedback As EvaluationFeedback(Of Integer, Integer)) As Integer
    3. If value < 0 Then Throw New ArgumentException("Positive value expected.")
    4. Return EvaluateByInverse(value, 0, (value + 1) \ 2, Function(l, r) l + (r - l) \ 2, Function(v) v * v, Function(l, r) l.CompareTo(r), feedback)
    5. End Function
    6. Shared Function EvaluateByInverse(Of TResult, TValue)(
    7. value As TValue,
    8. lower As TResult,
    9. upper As TResult,
    10. averageFunction As Func(Of TResult, TResult, TResult),
    11. inverseFunction As Func(Of TResult, TValue),
    12. comparison As Comparison(Of TValue),
    13. feedback As EvaluationFeedback(Of TResult, TValue)) As TResult
    14. If averageFunction Is Nothing Then Throw New ArgumentNullException("averageFunction")
    15. If inverseFunction Is Nothing Then Throw New ArgumentNullException("inverseFunction")
    16. If comparison Is Nothing Then Throw New ArgumentNullException("comparison")
    17. If feedback Is Nothing Then Throw New ArgumentNullException("feedback")
    18. Dim prev As TValue
    19. Dim avg As TResult = averageFunction(lower, upper)
    20. Dim invavg As TValue = inverseFunction(avg)
    21. Dim cmp As Integer = comparison(invavg, value)
    22. Do
    23. feedback(lower, upper, avg, invavg)
    24. If cmp < 0 Then ' f^-1(average(l, r)) < value
    25. lower = avg
    26. ElseIf cmp > 0 Then
    27. upper = avg
    28. Else
    29. Return avg
    30. End If
    31. prev = invavg
    32. avg = averageFunction(lower, upper)
    33. invavg = inverseFunction(avg)
    34. cmp = comparison(invavg, value) * Math.Abs(comparison(invavg, prev))
    35. Loop
    36. End Function


    Gruß
    ~blaze~

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „~blaze~“ ()

    Hab mir schon gedacht, das das nicht der aller schönste Code ist, aber er funktioniert und wenn man sich den Zweck und die Länge anschaut bin ich damit auch zufrieden, ich weiß das man sich gar nicht erst angewöhnen sollte so zu coden, aber nächsten Dienstag werde ich das Programm nicht mehr brauchen, und wahrscheinlich löschen .... und sowas möchte ich einfach nicht so viel Zeit investieren.
    MFG VBWorld
    Mathe ist für alle die, die nicht mit dem Taschenrechner umgehen können :D
    Ich denke das liegt daran, dass du auf absolute Gleichheit prüfst, diese ist aber so gut wie nicht erreichbar. Normalerweise definiert man ein Epsilon, das die tolerierte Abweichung angibt, und prüft dagegen.
    Und nur mal so, dieses Verfahren ist nicht optimal, ich würde da eher zu heron greifen.

    VBWorld schrieb:

    Wie genau prüfe
    Um solch Algorithmus zu testen, solltest Du in der Schleife jeweils den aktuellen Wert ausgeben:

    VB.NET-Quellcode

    1. Debug.WriteLine(value.ToString)
    Da siehst Du was passiert, und wenn die Genauigkeit nicht mehr zunimmt AndAlso die Schleife nicht abbricht, ist Dein Abbruchkriterium falsch.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!