Rundungsfehler bei double?



  • @Zeus: Bitte kopier doch mal genau diesen Quelltext hier und kompilier das. Da kommt definitiv 59 raus.

    #include <iostream>
    int main()
    {
    	double foo = 0.6;
    	int bar = (int)(foo * 100.0);
    	std::cout << bar;
    	return 0;
    }
    

    mfg, Bloops



  • Bashar schrieb:

    0,6 ist im Binärsystem periodisch.

    Na und? Mit float geht es ja... 😕



  • Bei mir kommt 60 raus.



  • Bloops schrieb:

    Bashar schrieb:

    0,6 ist im Binärsystem periodisch.

    Na und? Mit float geht es ja... 😕

    Bei float ist die Abweichung des gerundeten Wertes zu 0,6 halt positiv, bei double negativ.



  • Ah, das klingt plausibel, aber ist das normal bei C++? Sowas hätte ich vielleicht von JavaScript oder so erwartet, aber von C???? Ich mein, das darf doch eigentlich nicht passieren oder? bzw, wie kann ich das Problem lösen?

    @Optimizer: Welches System und Compiler?



  • Bloops schrieb:

    Ah, das klingt plausibel, aber ist das normal bei C++?

    Ja. Das hat auch überhaupt nichts mit C++ zu tun, sondern wie schon 2mal gesagt damit, dass sich 0,6 prinzipbedingt nicht genau darstellen läßt. 0,6 ist binär 0,1001100110011...



  • P4, Microsoft Visual C++ 7.0



  • #include <iostream> 
    #include <conio.h>
    using std::cout;
    using std::endl;
    
    int main() 
    { 
        float  zahl1 = 0.6f ;
        double zahl2 = 0.6  ;    
        cout << static_cast<int>( zahl1 * 100.0  ) << endl; 
        cout << static_cast<int>( zahl2 * 100.0  ) << endl; 
        getch();
    }
    


  • Bloops schrieb:

    @Zeus: Bitte kopier doch mal genau diesen Quelltext hier und kompilier das. Da kommt definitiv 59 raus.

    #include <iostream>
    int main()
    {
    	double foo = 0.6;
    	int bar = (int)(foo * 100.0);
    	std::cout << bar;
    	return 0;
    }
    

    mfg, Bloops

    Habe es gemach kommt immer noch 60 raus.
    Ich habe Visual Studio 2002 .NET

    Bei Fließkommazahlen ist es üblich, dass Ganzzahlen nicht direkt auf eine Fließkommazahl abgebildet werden kann, dass das schon mit zu eine kleine Zahl passiert ist mir merkwürdig!



  • Bloops schrieb:

    Sowas hätte ich vielleicht von JavaScript oder so erwartet, aber von C????

    Tja, die Genauigkeit ist halt bei jeder Sprache begrenzt.



  • Nein. Lisp hat beispielsweise einen Typ RATIO, dessen Genauigkeit nur durch den verfügbaren Speicherplatz begrenzt wird.



  • in C++, wie wäre es mit einer klasse, die eine rationale zahl als bruch darstellt?
    oder bcd ziffern speichert?
    realisierbar ist vieles, und realisiert worden ist auch schon einiges 🙂



  • Ich meinte Builtins. Eine Klasse für Brüche etc. habe ich auch schon geschrieben. Aber bei irrationalen Zahlen ist Ende. Ja, man kann jetzt so argumentieren, dass man sich Typen schreiben kann die nur durch den Speicherplatz beschränkt sind, aber dieser ist ja auch in gewissem Maße beschränkt 🙂 .



  • Übrigens ist es schon eine lustige Idee, von C++ zu erwarten, dass es in der Beziehung besser ist als Javascript. Die Arithmetik-Unterstützung von C++ ist -- bedingt durch das C-Erbe -- eine der primitivsten überhaupt.

    Edit: RATIO ist natürlich eingebaut, sonst hätt ich das Beispiel nicht gebracht.



  • was haben die Rundungsprobleme mit irgendeiner Sprache zu tun.

    Wenn man da maulen will, muss man sich über "ANSI/IEEE Standard 754-1985 for Binary Floating-Point Arithmetic" mukieren. denn da sind die Z Zahlenformnate und ihre Fähigkeiten definiert.

    In einer 32 BIT Zahl mit einem Bit sign 8 Bit exponent und 23 Bit Mantisse
    oder
    In einer 64 BIT Zahl mit einem Bit sign 11 Bit exponent und 52 Bit Mantisse

    gibt es nur eine definierte Genauigkeit (32 Bit 2-23 or 1.192 x 10-7 , 64 Bit 2-52 or 2.220 x 10-16)

    Dieses Zahlenformat ist den FPU der CPU´s implementiert und betimmen somit die Genauigkeit, egal für welche Sprache. Es gibt zwar ein Paar SW Implemtierungen mit 80 und 128 Bit aber diese haben dieselben Probleme zwar bei kleineren Delta´s. (Ja mir ist bekannt das Intel und AMD intern in den FPU´s - nicht die SSE... - immer mit 80 Bit rechnen und das es auch Methoden gibt an dieses Format heranzukommen -BC 3.1 für Dos -, Übrigens die rechnen immer 80 Bit und nur beim load oder store wird in das angeforderte Format gewandelt)

    jede Zahl die sich nicht ohne Rest mit den oben aufgeführten Bit´s darstellen läßt kann die oben gezeigten Ungenauigkeiten haben.

    Quellen
    http://www.math.byu.edu/~schow/work/IEEEFloatingPoint.htm


Anmelden zum Antworten