Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Nils
Anmeldungsdatum: 24.03.2006 Beiträge: 191
|
Verfasst am: 27.01.2016, 21:03 Titel: Rechenproblematik |
|
|
Guten Abend Gemeinde!
Bei der Rechnung cos(90*pi/180) ergibt sich -4,371139E-08. statt Null.
Pi errechne ich mit 4*ATN(1).
Wie bringe ich den Wert auf Null, ohne die Ungenauigkeit zB durch eine Definitionsgleichung abzufangen?
grüsse Nils _________________ Kontrolliert die Politik! Laßt nicht die Politik Euch kontrollieren! Das sind Eure Angestellten! Lasst Sie das spüren!!! |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4599 Wohnort: ~/
|
Verfasst am: 27.01.2016, 21:23 Titel: |
|
|
Ohne die Ungenauigkeit abzufangen - gar nicht. Das ginge höchstens mit symbolischen Rechnen.
FreeBASIC rechnet nun einmal, so wie die meisten Programmiersprachen, mit Gleitkommazahlen und den damit verbundenen Rundungsgenauigkeiten. Dein eingesetzter Wert 4*ATN(4) ist ja bereits nicht mehr PI, sondern ein auf 15 Stellen (oder so) gerundeter Wert. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 27.01.2016, 21:27 Titel: |
|
|
Du darfst bei Gleitkommazahlen keine genauen Ergebnisse erwarten. Zunächst hilft mal, Double- statt Single-Variablen zu verwenden, um die Genauigkeit zu erhöhen. Als nächstes gibt es zwei Dinge zu beachten:
1) Nicht auf exakte Werte prüfen.
Du willst prüfen ob das Ergebnis genau 0 ist?
Niemals Gleitkommazahlen auf Gleichheit prüfen!
Stattdessen:
Code: | If v > -1d-16 And v < 1d-16 Then ... |
1d-16 durch die gewünschte Präzision ersetzen.
2) Werte nicht unformatiert ausgeben. Verwende nur so viele Nachkommastellen zur Ausgabe wie nötig.
Code: | print using "#.########", v |
Oder ähnlich. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
|
|
Nach oben |
|
|
dreael Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 2508 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 27.01.2016, 23:01 Titel: |
|
|
Artikel aus meiner Sammlung:
http://www.dreael.ch/Deutsch/BASIC-Knowhow-Ecke/Gleitkommazahlen.html
Gilt aber für so ziemlich alle Programmiersprachen und Compiler. Ausgenommen wäre höchstens eine Zahlenklasse (an Maple denken!), welche intern alles als algebraische Ausdrücke darstellt.
Aber reguläre Fliesskommazahlen für den (bei den heuten CPUs integrierten) mathematischen Coprozessor verwenden alle IEEE 754 als interne Darstellung, womit zwangsweise die von Dir beobachteten Effekte entstehen. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
|
Nils
Anmeldungsdatum: 24.03.2006 Beiträge: 191
|
Verfasst am: 28.01.2016, 17:04 Titel: |
|
|
@ alle:
Danke für Eure Beiträge.
Habe schon befürchtet, dass da wenig zu machen ist.
Werde den Fehler also abfangen und das Ergebnis einfach als Null definieren.
grüsse Nils _________________ Kontrolliert die Politik! Laßt nicht die Politik Euch kontrollieren! Das sind Eure Angestellten! Lasst Sie das spüren!!! |
|
Nach oben |
|
|
dreael Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 2508 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 29.01.2016, 10:05 Titel: |
|
|
Ich würde an Deiner Stelle eine Art ungefähr-Gleich definieren. Also statt
halt
Code: | If ungefaehrGleich(a, b) Then |
mit
Code: | Const Toleranz As Double = 1E-12
Function ungefaehrGleich(a As Double, b As Doube) As Integer ' sollte eigentlich Boolean sein
ungefaehrGleich = Abs(a - b) <= Toleranz
End Function |
Nebenbei: CAD-Systeme sind ein praktischer Anwendungsfall, z.B. wenn bestimmt werden muss, ob einer zu schraffierende Fläche geschlossen ist oder nicht, weil es bedingt durch die Maschinenzahlengenauigkeit auch kleine Lücken geben könnte, die aber gemäss Ablauf der geometrischen Konstruktion gar nicht existieren dürften. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
|
|