C Programm max. Geschwindigkeit vom Auto berechnen



  • Hallo,

    ich habe eine Problemstellung von meinem Professor bekommen und habe dies auch gelöst. Nur hat er uns gesagt dass das Ergebnis auf die Kommastelle genau stimmen muss, ansonsten erhalte ich keine Punkte. Bei mir weicht die 15.te Nachkommastelle von der Lösung ab und komme nach langer Zeit nicht selbst auf den Fehler. Wäre sehr freundlich wenn mir jemand einen Tipp geben könnte. Hier die Aufgabe:

    Es ist eine .csv Datei gegeben welche Steuerbefehle von einem Auto enthält. Das Auto bewegt sich in zwei Dimensionen und startet an der Position (0,0) und zeigt nach rechts
    Die .csv Datei enthält zwei durch Kommas (,) getrennte Werte für jeden von 100 Zeitschritten der jeweils eine Sekunde lang ist. Die zwei Werte sind:

    1. Beschleunigung des Autos in m/s^2 in der Richtung in die es aktuell zeigt.
    2. Die ausführende Rotation des Autos ausgehend von der aktuellen Richtung in Radianten.

    Das Auto führt die folgenden Schritte für jeden Zeitschritt in dieser Reihenfolge aus:

    1. Das Auto rotiert
    2. Das Auto beschleunigt in Fahrtrichtun (positiveWerte) oder entgegen der Fahrtrichtung (negative Werte)
    3. Das Auto verändert seine Position

    Der Einfachheit halber nehmen wir an, dass die Aktionen des Autos ohne Zeitverlust ausgeführt werden. Das Auto beschleunigt also ohne Zeitverlust auf die neue Geschwindigkeit so als hätte es die gegebene Beschleunigung für eine Sekunde erfahren. Berechnen Sie die maximale Geschwindigkeit;
    Die Lösung ist: 5.273075844681093
    Ich komme auf: 5.273075844681092

    Hier ist mein Code: https://onlinegdb.com/I20uiuUIS



  • @jasmin89 Gibst du auch das Password mit?



  • @jasmin89: Du solltest den "Share"-Button benutzen und dessen Link hier posten.

    PS: Die letzte Ziffer einer Fließkommazahl ist immer ungenau - da kommt es häufig auf die Reihenfolge der Operationen an (z.B. a * b / c vs. a / c * b)



  • Sorry hatte nicht den öffentlichen Link geposted. Das müsste nun gehen: https://onlinegdb.com/I20uiuUIS



  • @jasmin89 Deine Variablen sind nicht initialisiert.

    Die können dann einen beliebigen Wert haben.

    Da sollte auch der Compiler warnen.

    Du kannst auch fscanf(fp, "%lf,%lf,%lf", wert1, …) zum lesen der Datei nutzen.



  • Was mir auf Anhieb auffällt:

    • direction ist uninitialisiert...
    • sqrt(vx*vx + vy*vy)solltest du nur einmalig berechnen und in einer Variablen speichern

    Generell beachte die Warnungen des Compilers (mit Option -Wall).

    Und einige der Eingabewerte haben eine höhere Anzahl von signifikanten Ziffern (> 16), als ein double aufnehmen kann, s. untere Tabelle in Zahlenformate und andere Festlegungen des IEEE-754-Standards.





  • @Th69 sagte in C Programm max. Geschwindigkeit vom Auto berechnen:

    • sqrt(vx*vx + vy*vy)solltest du nur einmalig berechnen und in einer Variablen speichern

    Eigentlich braucht man das auch nur für die Ausgabe berechnen.



  • Danke für die Tipps, habe einige umgesetzt. Bin gar nicht auf die Idee gekommen dass bereits die Eingelesenenen Fließkommazahlen eine höhere Anzahl von signifikanten Stellen haben als der Datentyp. Ich verwende nicht mehr atof sonder strtold. Dabei verwende ich den Datentyp long double nur für das einlesen der Daten. Ich komme nun genau auf das Ergebnis:
    https://onlinegdb.com/iE7pX7Wy2

    Komischerweiße wenn ich fscanf verwende (und auch für die Berechnung long double verwende) komme ich auf ein anderes Ergebnis:
    https://onlinegdb.com/vCol6iQGd

    Af jeden Fall verwende ich die Version wo ich auf die richtige Lösung komme.


  • Mod

    @jasmin89 sagte in C Programm max. Geschwindigkeit vom Auto berechnen:

    Danke für die Tipps, habe einige umgesetzt. Bin gar nicht auf die Idee gekommen dass bereits die Eingelesenenen Fließkommazahlen eine höhere Anzahl von signifikanten Stellen haben als der Datentyp. Ich verwende nicht mehr atof sonder strtold. Dabei verwende ich den Datentyp long double nur für das einlesen der Daten. Ich komme nun genau auf das Ergebnis:
    https://onlinegdb.com/iE7pX7Wy2

    Komischerweiße wenn ich fscanf verwende (und auch für die Berechnung long double verwende) komme ich auf ein anderes Ergebnis:
    https://onlinegdb.com/vCol6iQGd

    Das liegt nicht an scanf, sondern eben daran, dass du deinen Variablen einen anderen Typ gegeben hast. Warum sollte das komisch sein, dass bei anderer Genauigkeit eine andere Genauigkeit herauskommt?



  • @jasmin89 sagte in C Programm max. Geschwindigkeit vom Auto berechnen:

    Nur hat er uns gesagt dass das Ergebnis auf die Kommastelle genau stimmen muss, ansonsten erhalte ich keine Punkte. Bei mir weicht die 15.te Nachkommastelle von der Lösung ab und komme nach langer Zeit nicht selbst auf den Fehler.
    ...
    Die Lösung ist: 5.273075844681093
    Ich komme auf: 5.273075844681092

    Hab mir deinen Code nicht angesehen, aber ich behaupte mal diese Forderung ist Quatsch.

    Selbst wenn man exakt den selben Algorithmus verwendet, macht es einen Unterschied z.B. in welcher Reihenfolge man Berechnungen ausführt. Mathematisch ist das bei z.B. Addition egal. Bloss wenn man es mit am Computer mit Gleitkommazahlen rechnet, können dabei unterschiedliche Ergebnisse rauskommen. Der Grund ist dass bei Rechnungen mit Gleitkommazahlen nach jedem Rechenschritt gerundet wird. Und zwar nicht auf eine fixe Anzahl von Nachkommastellen sondern auf eine fixe Anzahl von signifikanten Stellen (im Binärsystem).

    Als Beispiel um das zu verdeutlichen nehmen wir an wir hätten dezimale Gleitkommazahlen die auf zwei signifikante Stellen runden. Und damit wollen wir drei Zahlen addieren: 0.14, 0.033 und 1.1.

    0.14 + 0.033 = 0.173 = 0.17 gerundet
    0.17 + 1.1 = 1.27 = 1.3 gerundet

    In anderer Reihenfolge gerechnet:

    1.1 + 0.14 = 1.24 = 1.2 gerundet
    1.2 + 0.033 = 1.233 = 1.2 gerundet

    Oops

    Weiters kommt dann auch noch dazu dass manche Compiler, je nach Einstellung, selbst bestimmte Umformungen durchführen. Bzw. je nach Compiler und Einstellung kann es auch sein dass Zwischenergebnisse in den guten alten 80 Bit Gleitkommaregistern gehalten werden - ohne nach jedem Rechenschritt auf 64 Bit Genauigkeit beschnitten zu werden. Dabei kann dann auch schnell ein anderes Ergebnis rauskommen als wenn man durchgehen mit nur 64 Bit rechnet.

    Dieses Problem liesse sich lösen indem man die genauen Compiler-Einstellungen vorgibt. Das Problem mit der Reihenfolge ist aber fundamental und bleibt.



  • @DirkB sagte in C Programm max. Geschwindigkeit vom Auto berechnen:

    @Th69 sagte in C Programm max. Geschwindigkeit vom Auto berechnen:

    • sqrt(vx*vx + vy*vy)solltest du nur einmalig berechnen und in einer Variablen speichern

    Eigentlich braucht man das auch nur für die Ausgabe berechnen.

    Die Wurzel, ja. Den vx*vx + vy*vy Teil muss man schon ausrechnen. Wie sollte man sonst das Maximum finden?



  • @hustbaer sagte in C Programm max. Geschwindigkeit vom Auto berechnen:

    Den vxvx + vyvy Teil muss man schon ausrechnen. Wie sollte man sonst das Maximum finden?

    Klar.
    Aber bei der anschließenden Zuweisung an max_speed traue ich dem Compiler zu, dass er sich den Wert noch vom Vergleich merkt - zumindest wenn man Optimierung erlaubt.


  • Mod

    @hustbaer sagte in C Programm max. Geschwindigkeit vom Auto berechnen:

    Hab mir deinen Code nicht angesehen, aber ich behaupte mal diese Forderung ist Quatsch.

    Selbst wenn man exakt den selben Algorithmus verwendet, macht es einen Unterschied z.B. in welcher Reihenfolge man Berechnungen ausführt. Mathematisch ist das bei z.B. Addition egal. Bloss wenn man es mit am Computer mit Gleitkommazahlen rechnet, können dabei unterschiedliche Ergebnisse rauskommen. Der Grund ist dass bei Rechnungen mit Gleitkommazahlen nach jedem Rechenschritt gerundet wird. Und zwar nicht auf eine fixe Anzahl von Nachkommastellen sondern auf eine fixe Anzahl von signifikanten Stellen (im Binärsystem).

    Was dann der Grund ist, wieso man in Numerik lernen sollte, worauf man warum achten muss, bei der Wahl der Reihenfolge. Denn es gibt halt Reihenfolgen (oder gar ganze Rechenwege!), bei denen das Ergebnis genauer ist als bei anderen, und das kann man auch begründen mit Wissen um Fließkommazahlen.

    Aber hier hast du vermutlich Recht und es ist Quatsch; der Prof will wahrscheinlich nur ein simples Kriterium für die Bewertung haben. Wenn die Feinheiten der Fließkommatechnik ein Thema gewesen wären, hätte die Aufgabe anders ausgesehen (Man kann ganz einfach realistische Aufgaben stellen, wo das Ergebnis sich bei falschem Rechenweg um Größenordnung unterscheiden würde) und jasmin89 hätte andere Fragen gestellt.



  • @SeppJ

    Aber hier hast du vermutlich Recht und es ist Quatsch; der Prof will wahrscheinlich nur ein simples Kriterium für die Bewertung haben.

    Ja, glaube ich auch.

    Natürlich ist das Beispiel so einfach dass dabei wirklich nicht viel schief gehen kann. Naiv ausprogrammiert gibt es da ja eigentlich keine Operationen die man in unterschiedlicher Reihenfolge machen könnte.

    Wo ich allerdings ein echtes Problem bei diese Aufgabe sehe sind die sin und cos Funktionen. Soweit ich weiss sind die in quasi keiner Implementierung exakt (=nur der unvermeidbare Rundungsfehler) - sondern können auch manchmal um etwas mehr als 0.5 ULP abweichen. Und natürlich machen auch nicht alle Implementierungen die selben Fehler.



  • @hustbaer Danke für die Informationen, wieder etwas gelernt.

    Auf jeden Fall wird der Professor schon zufrieden sein. Keine Ahnung warum aber er hat immer ein Hawaii T-Shirt an.🤓


  • Gesperrt

    Hello this is Gulshan Negi
    Well, if you are experiencing an error that is causing a difference in the 15th decimal place of your calculations, it can be challenging to determine the source of the error. However, there are several strategies that you can use to identify and resolve the issue, such as checking your calculations, inputs, software settings, rounding, and considering the limitations of the problem. If you are still struggling, seeking assistance from your professor or a tutor can be beneficial. Remember, accuracy is important in academic and professional settings, so it's essential to take the time to identify and correct any errors in your work.
    Thanks


Anmelden zum Antworten