|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Mat Senior JLI'ler
Alter: 36 Anmeldedatum: 17.09.2005 Beiträge: 205 Wohnort: Koblenz Medaillen: Keine
|
Verfasst am: 29.04.2007, 10:17 Titel: float-Genauigkeit |
|
|
Hey,
es ist ja bekannt, das Variablen vom Typ float bei Rechenoperationen ungenau sind.
Ich sitze derzeit jedoch an einer Anwendung, wo diese Ungenauigkeit zum Tragen kommt.
Es scheitert leider an so kleinigkeiten wie hier:
CPP: | _Zoom -= ZOOM_SPEED; // Abweichung von Ergebnis 0,000477%
_Zoom *= 100.f; // Abweichung von Ergebnis 0,000008%
_Zoom = abs(_Zoom);
_Zoom /= 100.f;
|
Die erste Zeile alleine errechnet eine Ungenauigkeit von 0,000477%. Wenn ich dann das Ergebnis runde (hier kommt es nur auf die 2. Stelle hinter dem Komma an - wie der Code zeigt) hält sich die Ungenauigkeit in Grenuen (nurnoch 0,000008%) -> gibt es evtl. einen Variablentyp oder spezielle Funktionen, mit denen ich Exakte Werte erhalte ? _________________ - - - - - - - - - - - - - - - - - - - -
-> http://www.sea-productions.de
-> http://www.krawall.de
- - - - - - - - - - - - - - - - - - - - |
|
Nach oben |
|
|
manu Super JLI'ler
Alter: 35 Anmeldedatum: 09.03.2006 Beiträge: 327 Wohnort: allgäu (DE) Medaillen: Keine
|
Verfasst am: 29.04.2007, 10:37 Titel: Re: float-Genauigkeit |
|
|
Mat hat Folgendes geschrieben: | Hey,
es ist ja bekannt, das Variablen vom Typ float bei Rechenoperationen ungenau sind.
Ich sitze derzeit jedoch an einer Anwendung, wo diese Ungenauigkeit zum Tragen kommt.
Es scheitert leider an so kleinigkeiten wie hier:
CPP: | _Zoom -= ZOOM_SPEED; // Abweichung von Ergebnis 0,000477%
_Zoom *= 100.f; // Abweichung von Ergebnis 0,000008%
_Zoom = abs(_Zoom);
_Zoom /= 100.f;
|
Die erste Zeile alleine errechnet eine Ungenauigkeit von 0,000477%. Wenn ich dann das Ergebnis runde (hier kommt es nur auf die 2. Stelle hinter dem Komma an - wie der Code zeigt) hält sich die Ungenauigkeit in Grenuen (nurnoch 0,000008%) -> gibt es evtl. einen Variablentyp oder spezielle Funktionen, mit denen ich Exakte Werte erhalte ? |
exakte werte wirst du nie erhalten
3/9.2 ist exakt
0,326086956521 nicht ^^
aber wenn mich nicht alles täuscht ist double doch etwas genauer... |
|
Nach oben |
|
|
Maxim Senior JLI'ler
Anmeldedatum: 28.03.2004 Beiträge: 249
Medaillen: Keine
|
Verfasst am: 29.04.2007, 10:53 Titel: |
|
|
ja, double ich genauer. die ganze ungenauigkeit liegt an dem internen aufbau von float und double.
wenn du es wirklich genau haben willst, dann schau dir das an:
http://cplus.kompf.de/artikel/gmp.html |
|
Nach oben |
|
|
PeaceKiller JLI Master
Alter: 36 Anmeldedatum: 28.11.2002 Beiträge: 970
Medaillen: Keine
|
Verfasst am: 29.04.2007, 11:23 Titel: |
|
|
Und wenn du`s ganz genau haben willst kannst du long double verwenden. _________________ »If the automobile had followed the same development cycle as the computer, a Rolls-Royce would today cost $100, get a million miles per gallon, and explode once a year, killing everyone inside.«
– Robert X. Cringely, InfoWorld magazine |
|
Nach oben |
|
|
Mat Senior JLI'ler
Alter: 36 Anmeldedatum: 17.09.2005 Beiträge: 205 Wohnort: Koblenz Medaillen: Keine
|
Verfasst am: 29.04.2007, 12:26 Titel: |
|
|
long double verwende ich teilweise auch schon - kann zwar viele Stellen hinter dem Komma fassen, hat aber sehr ähnliche Probleme mit der Genauigkeit wie float.
http://cplus.kompf.de/artikel/gmp.html sieht interessant aus, außerdem überlege ich, einfach eine Bruchklasse zu schreiben, so dass Ungenauigkeit wenn überhaupt bei einer einzigen Division eintreten.
Danke _________________ - - - - - - - - - - - - - - - - - - - -
-> http://www.sea-productions.de
-> http://www.krawall.de
- - - - - - - - - - - - - - - - - - - - |
|
Nach oben |
|
|
AFE-GmdG JLI MVP
Alter: 45 Anmeldedatum: 19.07.2002 Beiträge: 1374 Wohnort: Irgendwo im Universum... Medaillen: Keine
|
Verfasst am: 29.04.2007, 12:41 Titel: |
|
|
In den allermeisten Fällen sollte Float eine ausreichende Genauigkeit haben, wenn diese nicht reicht, kann man noch auf Double zurückgreifen. mit 63 Bit Verarbeitungslänge ist Double allerdings nicht mehr so schnell wie ein 16 Bit Float. Long Double verwendet meines Wissens nach 128 Bit, ist aber im Vergleich zu Double mindestens 4x langsamer.
Wenn du wie in deinem Fall nur 2 Nachkommastellen benötigst würde ich versuchen, die Berechnung auf Integer-Basis durchzuführen und im letzten Schritt den Int in ein Float umrechnen... (FloatVal = IntVal / 100.0f) _________________
CPP: | float o=0.075,h=1.5,T,r,O,l,I;int _,L=80,s=3200;main(){for(;s%L||
(h-=o,T= -2),s;4 -(r=O*O)<(l=I*I)|++ _==L&&write(1,(--s%L?_<(L)?--_
%6:6:7)+\"World! \\n\",1)&&(O=I=l=_=r=0,T+=o /2))O=I*2*O+h,I=l+T-r;} |
|
|
Nach oben |
|
|
GreveN JLI Master
Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 29.04.2007, 12:59 Titel: |
|
|
AFE-GmdG hat Folgendes geschrieben: | In den allermeisten Fällen sollte Float eine ausreichende Genauigkeit haben, wenn diese nicht reicht, kann man noch auf Double zurückgreifen. mit 63 Bit Verarbeitungslänge ist Double allerdings nicht mehr so schnell wie ein 16 Bit Float. Long Double verwendet meines Wissens nach 128 Bit, ist aber im Vergleich zu Double mindestens 4x langsamer.
Wenn du wie in deinem Fall nur 2 Nachkommastellen benötigst würde ich versuchen, die Berechnung auf Integer-Basis durchzuführen und im letzten Schritt den Int in ein Float umrechnen... (FloatVal = IntVal / 100.0f) |
Argh... was meinst du mit 63 Bit Verarbeitungslänge? Double dürfte auf den meisten heutigen Plattformen 64 Bit lang sein, 1 Bit Vorzeichen, 52 Bit Mantisse und 11 Bit Exponent, wirklich langsamer muss es nicht sein, hängt eben von der CPU-Architektur ab. Float wird wohl auf keiner gängigen Hardware 16 Bit sein, sondern 32 Bit - 1 Bit Vorzeichen, 23 Bit Mantisse, 8 Bit Exponent - das schreibt der IEEE 754-Standard vor. Long-Double ist auf den meisten Plattformen 80 Bit groß, mindestens jedoch 78, aber das gibt IEEE 754 nicht genau vor.
Float bietet 7-8 Stellen Genauigkeit, Double 15-16 und Long-Double 19-20. |
|
Nach oben |
|
|
AFE-GmdG JLI MVP
Alter: 45 Anmeldedatum: 19.07.2002 Beiträge: 1374 Wohnort: Irgendwo im Universum... Medaillen: Keine
|
Verfasst am: 29.04.2007, 19:13 Titel: |
|
|
Stimmt wohl. So genau hatte ich die Bitanzahl wohl nicht mehr im Kopf.
Hab die Bits durcheinandergewürfelt - tut mir leid.
Trotzdem ist eine Long Double Berechnung wesentlich langsamer als Double, da für ihre Berechnung mehrere CPU-Schritte in Microcode notwendig sind, während Floats noch komplett in die Prozessorregister passen. Bei Doubels muss auch schon gesplittet werden, wenn man nicht schon einen neuen 64-Bit-Prozessor hat... (und das Programm für 64 Bit Kompiliert wurde) _________________
CPP: | float o=0.075,h=1.5,T,r,O,l,I;int _,L=80,s=3200;main(){for(;s%L||
(h-=o,T= -2),s;4 -(r=O*O)<(l=I*I)|++ _==L&&write(1,(--s%L?_<(L)?--_
%6:6:7)+\"World! \\n\",1)&&(O=I=l=_=r=0,T+=o /2))O=I*2*O+h,I=l+T-r;} |
|
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|