Visual C++ rechnet falsch !!!
-
schau dir an, wie gleitkommazahlen im rechner festgelegt wurden
http://de.wikipedia.org/wiki/Gleitkommazahl
mantisse, exponent, berechnungsvorschriften..ps: vergleiche von gleitkommazahlen funktionieren nicht.
rechne mit integer?
-
Das ist immer so. Runde einfach. Woher kommt denn diese "round"-Funktion, die du erwähnt hast?
Hier ein Beispiel für eine Rundungsfunktion (hat Martin Richter mal gepostet):
double RoundDouble(double dVal, int iPrec) { // Need a default? ASSERT(iPrec>=0); // Shift double dShift=1.0; for (int i=0; i<iPrec; ++i) dShift *= 10.0; // multiply and split (get integral Part) double dResult, dFrac; if (fabs(dFrac=modf(dVal*dShift,&dResult))>=0.5) // Remove Fraction dResult += dFrac<0.0 ? -1.0:1.0; // Shift it back return dResult/dShift; }
-
Also hab die Funktion gerade mal ausprobiert aber das bringt nichts. Bleibt immer auf 30.299999. Vllt. liegts an "int iPrec". Wie muss ich die Genauigkeit eingeben ? Habe mal ein paar Werte versucht aber geht trotzdem nicht.
-
Wenn du mal auf Ganzzahlen runden willst, kannst du dir eine aufwendige (und zeitintensive) Funktion sparen und das über ein Makro machen, z.B. so:
#define ROUNDTOINT(v) (int)(((v*10.)+5)/10)
-
Ah ok Danke. Aber zu 99 % muss ich halt mit Kommazahlen arbeiten und die Runden Funktion funktioniert bei mir auch nicht. Hat das eig. jeder dann oder kommt das nur ab und zu mal vor ?
-
pmb schrieb:
Ah ok Danke. Aber zu 99 % muss ich halt mit Kommazahlen arbeiten und die Runden Funktion funktioniert bei mir auch nicht. Hat das eig. jeder dann oder kommt das nur ab und zu mal vor ?
Nee, das ist immer so. Na ja, ein gerundeter double-Wert hat ja immer noch das Problem der internen Darstellung. Deine Ausgabe kann dann aber glatt auf z.B. 4 Stellen gerundet sein.
-
Eine Möglichkeit könnte z.B. http://gmplib.org/. Ist zwar in erster Linie zum Rechnen mit großen Zahlen gedacht. Ermöglicht aber wohl auch exaktes rechnen mit Gleitkommazahlen.
-
Und kann man die interne Darstellung irgendwie Richtig anzeigen lassen ? Oder rechnen da 64 Bit Prozessoren genauer ?
-
Multiplizier doch deine int's mit 10000, dann hast du deine vier Stellen Genauigkeit. Btw. dem Mathematiker reicht meist 'mit beliebiger Genauigkeit' und der Fehler den Du machst der liegt irgendwo bei 1*10^-6 und für double ungefähr bei 1*10^-15, bist Du sicher, daß das nicht genug ist?
-
Hallo pmb,
pmb schrieb:
Und kann man die interne Darstellung irgendwie Richtig anzeigen lassen ? Oder rechnen da 64 Bit Prozessoren genauer ?
Du hast das grundlegende Wesen der Fließkommadarstellung nicht richtig verstanden.
Die Fließkommazahl kann nicht so rechnen wie wir Menschen es so erwarten. Lese bitte die Beiträge und den Link auf Wikipedia genau durch.Wenn wir schon bei dem Thema sind, gleich vorneweg ein unerläßlicher Tipp: Unter anderem macht sich der Programmierer "strafbar", Fließkommazahlen auf Gleichheit zu prüfen! z.B.:
float f; f = 0.1; if ( f + 0.2 == 0.3 ) { printf( "gleich!" ); //Du wirst diesen String vermutlich nie sehen. } else { printf( "ungleich!" ); }Nun zu Deinem Problem: In Deinem Fall würde ich Festkomma-Zahlen (nicht Fließkomma!) verwenden.
D.h. eine Integer-Variable (am besten 32bit breit) mit dem Wert 1000 entspricht der Zahl 10,00. Und somit die gleiche Variable mit dem Wert 1 entspricht der gewünschten Zahl 0,01.pmb schrieb:
Oder rechnen da 64 Bit Prozessoren genauer ?
Normalerweise nein!
Fließkommazahlen werden üblicherweise in den Funktionen einer Bibliothek (z.B. math.lib) verarbeitet. Durch Angabe von float, double und long double (compilerabhängig!) legst Du die Genauigkeit und den Wertebereich der Fließkommavariablen von vorneherein fest.
Aber selbst mit einem long double (also 80 Bit Genauigkeit) hast Du den gleichen Effekt, nur statt des Ergebnisses "30.299999" bekommst Du dann halt "30.299999999999999999999" o.ä..Martin
-
pmb schrieb:
Und kann man die interne Darstellung irgendwie Richtig anzeigen lassen ? Oder rechnen da 64 Bit Prozessoren genauer ?
Wie intern gerechnet wird, und wie du das letztlich darstellen willst, sind zwei verschiedene Dinge. Das Rechnen geschieht schon genau genug, keine Sorge, die Darstellung kannst du dann auf x Stellen glatt gerundet machen.
-
Ja ok dann werde ich das mal versuchen. Das komische ist halt das es bei VC 6.0 noch gefunzt hat. Das mit den Fließkommazahlen hab ich schon verstanden. Der Prozessor muss das ja auch in Binärcode umrechnen.......
Aber es hätte ja sein können dass es irgendne Möglichkeit gibt.Danke nochmals für eure Antworten
-
pmb schrieb:
Das komische ist halt das es bei VC 6.0 noch gefunzt hat.
Wie meinst du das??
-
pmb schrieb:
Das komische ist halt das es bei VC 6.0 noch gefunzt hat. Das mit den Fließkommazahlen hab ich schon verstanden.
Das wage ich zu bezweifeln. Aber hier haben ja alle schon die richtigen Tipps gegeben. Ich habe auch ein Programm, welches Werte aus ner Messkarte ausliest. Die haben 6 Nachkommastellen. Verschiebe doch einfach das Komma na hinten und schneide den Rest ab. Da hast du ein paar Probleme weniger. Außerdem is das Vregleichen so auch möglich. Speziell bei deinem Beispiel geht das ja noch. Addiere mal mehrfach 1/3, da hast du noch viel größere Abweichungen.
-
Ich meine dass ich in VC++ 6.0 bei float Zahlen immer das rausbekommen habe was ich wollte also z.B 3.500000000 und nicht 3.4999999999999. Hatte das Problem im 6 er nur mit doubles. Floats funktionierten einwandfrei. Aber ist ja auch egal. Es ist Zeit für Veränderung -----> Visual c++ 2008

-
Quark. An der Floating Point Behandlung hat sich gar nichts geändert.
Dieses Problem gab es schon immer.Siehe auch:
http://www.mpdvc.de/artikel/FloatingPoint.htm
-
Hmm. Hatte es im 6 er aber echt nicht. Zumindest ist es mir beim debugggen nicht aufgefallen
-
pmb schrieb:
Hmm. Hatte es im 6 er aber echt nicht. Zumindest ist es mir beim debugggen nicht aufgefallen
Vielleicht hat der Debugger da schon verschönert dargestellt oder sowas...
-
Also ich hab damals auch unter 6.0 mit meinem Programm angefangen und da war das genauso wie bei 2003, also 35,0 endetet auch auf 34,9999999. Martin hat Recht, du kannst ja nichts an der Darstellung von Fließkommazahlen ändern. Sicher kanns Abweichungen in der Adressräumen von 64-Bit-Systemen im Vergleich zu 32-Bit-Systemen geben, aber das ändert an der Tatsache nichts, dass Ding in Exponent und Mantisse zerlegt werden muss und dafür eben nur eine gewisse Genauigkeit vorhanden ist.