Frage

Nach einer Stunde versucht, einen Fehler in meinem Code zu finden habe ich endlich den Grund. Ich habe versucht, einen sehr kleinen Schwimmer bis 1f hinzufügen, aber nichts geschieht. Bei dem Versuch, herauszufinden, warum ich fand, dass das Hinzufügen, dass kleine Schwimmer 0f perfekt funktioniert.

Warum ist das passiert? Ist dies mit ‚Größenordnungen‘ zu tun? Gibt es eine Abhilfe für dieses Problem?

Vielen Dank im Voraus.

Edit:

Die Umstellung auf doppelte Genauigkeit oder dezimal ist keine Option im Moment.

War es hilfreich?

Lösung

Da Präzision für eine mit einfacher Genauigkeit (32 Bit) Gleitkommawert ist etwa 7 Ziffern nach dem Dezimalpunkt. Was bedeutet, dass der Wert der Sie hinzufügen, ist im wesentlichen Null ist, zumindest wenn sie 1 hinzugefügt. Der Wert selbst kann jedoch in einem Schwimmer mühelos gespeichert, da der Exponent in diesem Fall klein ist. Aber, um es erfolgreich in dem 1 Sie die Exponenten der größeren Anzahl verwenden ... und dann die Ziffern nach den Nullen verschwinden in Runden.

Sie können double verwenden, wenn Sie mehr Präzision benötigen. Performance-weise dies sollte keinen Unterschied auf der heutigen Hardware machen und Speicher wird oft auch nicht so eingeschränkt, dass Sie denken über jede einzelne Variable.

EDIT: Wie Sie festgestellt, dass double Verwendung ist keine Option, die Sie verwenden können Kahan Summierung , wie akuhn wies in einem Kommentar aus.

kann eine andere Option, um Vermittler Berechnungen in doppelter Genauigkeit durchführen und danach wieder zu gieße float. Dies wird nur helfen, aber wenn es ein paar mehr Operationen als nur das Hinzufügen eine sehr kleine Zahl zu einem größeren.

Andere Tipps

Dies geschieht wahrscheinlich, weil die Anzahl der Ziffern der Präzision in einem Schwimmer konstant ist, aber der Exponent kann natürlich variieren.

Das bedeutet, dass, obwohl Sie Ihre kleine Zahl auf 0 hinzufügen können, können Sie es nicht zu einer Reihe hinzuzufügen erwarten, die einen Exponenten von 0 verschieden ist, da es einfach nicht genug Stellen genau links sein.

Sie sollten lesen Was jeder Informatiker wissen sollten über Gleitkommaarithmetik .

Es sieht aus wie es hat etwas mit Gleitkommagenauigkeit zu tun. Wenn ich Sie wäre, würde ich eine andere Art, wie decimal verwenden. Das sollte Präzision Fehler beheben.

Mit float, man bekommt nur eine Genauigkeit von etwa sieben Ziffern . Also Ihr number'll in 1f gerundet. Wenn Sie eine solche Nummer speichern möchten, verwenden Sie double statt

http://msdn.microsoft.com/en-us/library /ayazw934.aspx

Neben der akzeptierte Antwort: Wenn Sie viele kleine Anzahl und einige größere müssen zusammenzufassen, sollten Sie Kahan Summieren .

Wenn die Leistung ist ein Problem (weil Sie nicht double verwenden können), dann binäre Skalierung / Fest Punkt kann eine Option sein. floats werden als ganze Zahlen gespeichert, sondern von einer großen Anzahl (sagen wir, 2 ^ 16) skaliert. Zwischen Arithmetik mit (relativ schnell) Integer-Operationen durchgeführt. Die endgültige Antwort kann am Ende zu Gleitkomma umgewandelt zurück, um mit dem Skalierungsfaktor dividiert wird.

Dies ist oft getan, wenn der Zielprozessor eine Hardware fehlt Gleitkommaeinheit.

Sie sind mit dem f-Suffix auf Literale, die diesen Schwimmer statt verdoppelt machen. So Ihr sehr kleiner Schwimmer wird in dem größeren Schwimmer verschwinden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top