Float bei einer Nachkommastelle zu ungenau?

Spieleguru

Mitglied
Hallo,
mich hat jetzt ein kleines Problem wirklich Stundenlang beschäftigt. Ich wollte von einem Integer (in diesem Fall) 10% abziehen und diese dann zurückgeben. Das Ding ist bloß, ich möchte es nicht genau berechnen, sondern die Nachkommastellen sollen abgeschnitten werden von den errechneten 90%. Bei 162 müsste demnach 17(162 - (162*0,9) = 162 - 145[,8]), bei 160 16 (160 - 160*0,9) = 160 - 144) zurück geliefert werden:

Code:
public int berechneStatusWesenDiffInit(float WesenInit) // Woanders über float x = 0.9F initialisiert
        {
            int Init = 160;
            int StatusWesen = (int)(Init * WesenInit);

            return (StatusWesen > Init) ? StatusWesen - Init : Init - StatusWesen;
        }

Für den wert 160 wurde jedoch immer 17 zurück geliefert, für 110 12 usw. Ich habe ewig nach den Fehler gesucht, bis ich alle floats mal durch double ersetzt habe. Von da an lief alles einwandfrei!

Code:
public int berechneStatusWesenDiffInit(double WesenInit) // Woanders über double x = 0.9 initialisiert
        {
            int Init = 160;
            int StatusWesen = (int)(Init * WesenInit);

            return (StatusWesen > Init) ? StatusWesen - Init : Init - StatusWesen;
        }

Jetzt ist meine Frage: Warum? Was ist anders? Das einzige was mir einfallen würde, wäre, das als Ergebnis für StatusWesen nicht genau 144 raus kommt, sondern 143,999999... Das würde das Ergebnis erklären, da die Nachkommastellen ja bloß abgeschnitten werden. Jedoch hette ich gelesen, das Float bis zu 7 Nachkommastellen genau ist?
 
Zuletzt bearbeitet:

sheel

I love Asm
Hi

Naja, 143.9999999 sind ja auch 7 Nachkommastellen...
Wenn man das Ganze im Binärsystem macht, merkt man, dass da fast immer was verloren geht.

Eine andere Lösung, die komplett auf Kommazahlen und ihre Ungenauigkeit verzichtet:
C#:
//zahl ist ein int

if((zahl % 10) == 0)
    zahl /= 10;
else
{
    zahl /= 10;
    zahl++;
}

Gruß
 

Spieleguru

Mitglied
Diese Lösung scheint auch zu funktionieren. Danke dafür. Mal sehen, ob ich das noch umbaue, zugunsten der Ressourcen.

Zur Binärzahl: Aber werden Fließkommazahlen nicht praktisch als 2 Zahlen gespeichert? Eine die den Vorkommateil, und eine die den Nachkommateil angibt? Ich meine das so in Erinnerung zu haben, ist aber auch schon wieder ein Jahr her...
 

sheel

I love Asm
Zur Binärzahl: Aber werden Fließkommazahlen nicht praktisch als 2 Zahlen gespeichert?
Dann wären es ja keine Fließkommazahlen...

Vom Prinzip her kann man zB.
123.678
ja auch als
123678 * 0.001
und damit als
123678 * 10^(-3)
sehen.

So wird das auch abgespeichert.
Als Kommalose Zahl und einer Zahl,
wie oft mit 10 multipliziert/dividiert wird,
um die Originalzahl zu bekommen.
(In der Praxis ist das noch um einiges komplizierter).