0.01 / 10 = 0.0099999998 ??



  • Hi!

    Sorry für den blöden Titel, aber mir ist kein besserer eingefallen. Folgendes Problem:

    ich habe eine Float Variable multiplikator diese wird in einer for-schleife immer wieder durch 10 dividiert. Das geht auch gut bis zu dem zeitpunkt wo multiplikator den Wert 0.01 hat. Ab dann stimmen die Ergebnisse nicht mehr. 0.01 / 10 wäre dann 0.0099999998. (die anzahl der 9er hab ich jetzt nicht genau abgeschrieben).

    glaub dass es am Microsoft Visual Studio Compiler liegt, hatte aber noch nicht die Möglichkeit auf einem anderen Kompiler zu testen.

    hoffe es kann mir wer helfen.

    lg vogerl



  • glaubt eher, dass es an der genauigkeit von float liegt.



  • hab jetzt grad unter linux den gcc compiler versucht. selbes problem. hab schon probiert den multiplikator als double zu deklarieren, ähnliches problem (aber nicht das gleiche). bei double kommt dann 0.0010000000000000000001 heraus. wie kann ich dieses problem umgehen?

    lg vogerl



  • Du kannst das Problem umgehen, indem Du *keine* Floating-Point-Werte verwendest!!! (also kein float/double).
    Oder Du verwendest eine eigene Float-Bilbiothek, welche wesentlich höhere genauigkeit erlaubt (bzw. festkommazahlen ermöglicht).
    Oder Du rechnest einfach mit Ganzzahlen.



  • Jochen Kalmbach schrieb:

    Oder Du rechnest einfach mit Ganzzahlen.

    Welche aber auch irgendwann nicht mehr darstellbar sind mit normalen Integern etc.



  • Ganzzahlen grenzt das Gebiet ja nicht auf Integer ein



  • Das Problem ist, dass 0.01(dez) keine endliche Darstellung in den Binärzahlen hat:
    Die Binärdarstellung ist periodisch. Umrechnung inkl. Erklärung findet ihr unter http://www.arndt-bruenner.de/mathe/scripts/Zahlensysteme.htm
    Und damit passt 0.01(dez) in kein binäres Fließkommaformat ohne Konvertierungsfehler.



  • Taurin schrieb:

    Das Problem ist, dass 0.01(dez) keine endliche Darstellung in den Binärzahlen hat

    NaNaNa... das gilt *nur* für Fließkommazahlen!
    Eine 0.01(dec) mit einer Festkommazahl von 2 Nachkommastellen lässt sich sehr wohl 100%ig eindeutig darstellen (mal von der Quantenphysik abgesehen). Nämlich als 0x1(hex) oder 1(bin).

    Für eine LIB die Dir vielleicht weiterhelfen kann:
    http://www.apfloat.org/apfloat/



  • also nur mal zum rekapitulieren:

    0.01 ich kann 0.01 nicht durch 10 dividieren ohne Fehler? (ohne floatingpoint lib)
    Das mit den Ganzzahlen versteh ich nicht ganz, weil ja 0.01 auf keinen Fall (und daher wirklich nie) eine Ganzzahl ist, oder lieg ich da ziemlich falsch?

    wirklich sehr suspektes Problem. Weil ich immer geglaubt habe Computer wurden ursprünglich erfunden um genau und schnell zu rechnen. aber 0.01 durch 10 kann er nicht. sehr, sehr suspekt.

    aber danke auf jedenfall. vogerl



  • vogerl schrieb:

    0.01 ich kann 0.01 nicht durch 10 dividieren ohne Fehler? (ohne floatingpoint lib)
    Das mit den Ganzzahlen versteh ich nicht ganz, weil ja 0.01 auf keinen Fall (und daher wirklich nie) eine Ganzzahl ist, oder lieg ich da ziemlich falsch?

    0.01 kann man aber als "Festkommazahl mit 2 Nachkommastellen" darstellen. Das ist im Prinzip nichts anderes, als eine Ganzzahl die einfach einen "festen Teiler" hat. Somit wäre hier dann 0.01 dargestellt als 1.
    Im Finanzbereich würde man nie auf die Idee kommen mit Fliesskommazahlen zu rechnen... das wäre super, wenn man Geld unterschlagen will (Rundungsfehler sammeln 😉 ).
    Deshalb gibt es z.B. im .NET-Framework den Datentyp "decimal", der dieses Problem wie der Double (Float-Zahl) nicht hat.



  • Jochen Kalmbach schrieb:

    Taurin schrieb:

    Das Problem ist, dass 0.01(dez) keine endliche Darstellung in den Binärzahlen hat

    NaNaNa... das gilt *nur* für Fließkommazahlen!
    Eine 0.01(dec) mit einer Festkommazahl von 2 Nachkommastellen lässt sich sehr wohl 100%ig eindeutig darstellen (mal von der Quantenphysik abgesehen). Nämlich als 0x1(hex) oder 1(bin).

    Hmm, was bedeutet hier "Festkommazahl mit 2 Nachkommastellen"? Zwei Nachkommastellen im Binärsystem oder im Dezimalsystem?

    Bei ersterem sehe ich nicht, wie das gehen sollte, die erste Nachkommastelle im Binärsystem hat den Wert 1/2, die zweite 1/4. Die kleinste Zahl >0 ist also 1/4. Ich komme bei 0,01(dez)->bin auf einen nicht abbrechenden Bruch und das ist unabhängig davon, ob die die Zahl in einer Exponent-Mantisse-Darstellung hinschreibe oder einem Positional Number System, aka Festkommazahl. Kannst Du mal erklären, wie Du das meinst?



  • Natürlich dezimal 🙄


Anmelden zum Antworten