Schleifendurchläufe zählen
-
@mondorano
Du brauchst noch eine zweite Abbruchbedingung wenn du nicht willst dass die Schleife immer 100x durchläuft.
Dazu könntest du dir z.B. den Wert vom vorigen Durchlauf in einer 2. Variable merken (x_alt
oder so), und dannx
undx_alt
vergleichen. Und wenn die beiden sich "ähnlich genug" sind, dann halt abbrechen.Wobei der einfachste Test für "ähnlich genug" natürlich Gleichheit ist. Dabei kann es dann aber auf Grund verschiedener Effekte sein dass die Schleife 100x durchläuft trotz dem das Ergebnis schon nach wenigen Durchläufen exakt war.
Um das zu vermeiden kannst du eine "epsilon equals" Funktion wie die hier gezeigte
nearly_equal
verwenden:
https://stackoverflow.com/a/32334103/454519
-
@hustbaer Ist das Newton's Methode?
-
@Swordfish Es wird als Heron-Verfahren bezeichnet: https://de.wikipedia.org/wiki/Heron-Verfahren
Ist aber nix anderes als das Netwon-Verfahren fürx² - a = 0
.Also ja
-
@hustbaer thx
-
@Swordfish Auch lustig, falls du's noch nicht kennst: https://en.wikipedia.org/wiki/Fast_inverse_square_root
-
@hustbaer Kennt Doom nicht jeder? ^^
Ich habe gefragt weil ich mir oft schwer tu von Code auf irgendwann einmal gelesenes zu schließen. Ist nicht immer alles im aktiven Arbeitsspeicher.
Sollten die Werte fürx
nicht irgendwann anfangen zwischen zweien zu wechseln? Taugt das als Abbruchbedingung?
-
@Sicci Also am besten wäre glaube ich wenn ich dir die Aufgabe hier reinschicke dann ist das Verständnis auch besser denke ich.
Habe das hier einfach mal hochgeladen. Hoffe ich darf das hier reinschicken.
-
@Swordfish sagte in Schleifendurchläufe zählen:
Sollten die Werte für x nicht irgendwann anfangen zwischen zweien zu wechseln? Taugt das als Abbruchbedingung?
Ich würde sagen: vermutlich ja, es sollte maximal ein Pendeln zwischen zwei Werten sein.
Ich hatte das auch schon alles runtergetippt. Nur ist mir dann wieder eingefallen dass das mit Gleichheit bei Floating-Point halt so eine Sache ist.
Wenn du diverse "fast math" Optimierungen an hast, und die passende Architektur + Compiler, dann kann es sein dass die Werte nie gleich testen obwohl sich schon lange nichts mehr ändert. Da hilft dann auf den vorletzten Wert prüfen auch nix mehr. Und zwar wenn der Compiler z.B. den aktuellen Wert von
x
noch in einem (breiteren) Register hat, den Wert vonx_alt
bzw.x_altalt
aber aus dem Speicher liest. x87 hat z.B. 80 Bit breite FPU Register, da kann sowas passieren. Mit SSE sollte es mMn. nicht mehr vorkommen.
Ebenso sollte es mit passenden Compiler-Einstellungen nicht passieren.
-
Wenn ich die Werte vor dem Vergleich explizit in einen
double
"zwinge" sollte das auf jeden Fall funktionieren.
-
@mondorano sagte in Schleifendurchläufe zählen:
@Sicci Also am besten wäre glaube ich wenn ich dir die Aufgabe hier reinschicke dann ist das Verständnis auch besser denke ich.
Habe das hier einfach mal hochgeladen. Hoffe ich darf das hier reinschicken.
So wie die Aufgabe formuliert ist, reicht ein Test auf Gleichheit mit dem Wert aus dem letzten Durchlauf.
-
@Swordfish sagte in Schleifendurchläufe zählen:
Wenn ich die Werte vor dem Vergleich explizit in einen
double
"zwinge" sollte das auf jeden Fall funktionieren.Jain.
Laut MS-Doku nicht: https://docs.microsoft.com/en-us/cpp/build/reference/fp-specify-floating-point-behavior?view=msvc-160fast
The
/fp:fast
option allows the compiler to reorder, combine, or simplify floating-point operations to optimize floating-point code for speed and space. The compiler may omit rounding at assignment statements, typecasts, or function calls.Wobei ich im Code nur einen Unterschied zwischen "fast" und "strict" sehen kann, "fast" und "precise" sind dagegen gleich: https://godbolt.org/z/6KxTae
Laut Doku müsste es auch bei "precise" schon passen, also... pfuh. Keine Ahnung
-
@hustbaer sagte in Schleifendurchläufe zählen:
Keine Ahnung
I know that feeling.
@hustbaer sagte in Schleifendurchläufe zählen:
The compiler may omit rounding at assignment statements, typecasts, or function calls.
Hm. Initialization steht da nicht
-
@Swordfish
ps: GCC hat gleich gar keinen Modus indem mit x87 korrekt gerundet wird: https://godbolt.org/z/684EGr
Siehe auch https://gcc.gnu.org/wiki/x87noteps2: Weil ich's grad noch ausprobiert habe:
x = static_cast<MY_FLT>(x);
reicht nicht
-
Also ich habe die ganze Zeit versucht irgendwas hinzubekommen um mir die Schleifendurchläufe korrekt anzeigen zu lassen aber das lohnt sich noch nicht mal hier rein zu senden. Keine Ahnung wie ich das machen soll.
-
@mondorano
Mitcout << Dings;
kannst du den Inhalt/Wert vonDings
ausgeben.Wie du es in deinem Programm schon selbst verwendet hast, kannst du auch mehrere
<<
kombinieren, alacout << i << " Schleifendurchläufe";
Und wenn duendl
ausgibst bekommst du einen Zeilenumbruch.Jetzt schreib in deine Schleife etwas rein mit dem du den aktuellen Durchlauf sowie den aktuellen Wert von
x
ausgibst.Sollte nicht so schwer sein.
Ansonsten melde dich nochmal mit dem was sich deiner Meinung nach nicht lohnt hier zu zeigen. Wir werden dir gerne helfen wenn du wo was nicht verstehst, aber so direkt machen werden wir die Aufgabe nicht für dich. Also zumindest ich nicht.
-
@hustbaer Ich habe nicht umsonst
@Swordfish sagte in Schleifendurchläufe zählen:
Initialization
geschrieben.
-
@Swordfish Ich nix versteh.
Die Doku ist zu MSVC, mein Beispiel mit GCC.
Und davon abgesehen:MY_FLT force_precision(MY_FLT val) { MY_FLT /* ohne volatile */ v = val; return v; }
reicht auch nicht. Das
volatile
ist da wirklich nötig.
-
@hustbaer sagte in Schleifendurchläufe zählen:
reicht auch nicht.
Danke. Du hast meine Träume damit zerstört
-
@Swordfish sagte in Schleifendurchläufe zählen:
Danke. Du hast meine Träume damit zerstört
Das kann ich anscheinend gut.
mondorano hat sich auch gleich wieder abgemeldet. Dabei war ich nichtmal besonders unfreundlich
-
@hustbaer sagte in Schleifendurchläufe zählen:
Das kann ich anscheinend gut.
Das ist doch gut! "enttäuscht" bedeutet Klarheit.
(Und danke für die Tests für die ich zu faul war )@hustbaer sagte in Schleifendurchläufe zählen:
mondorano hat sich auch gleich wieder abgemeldet. Dabei war ich nichtmal besonders unfreundlich
Du warst garnicht unfreundlich.