Casting auf int und Gleitkommafehler?

8
%Vor%

myRandom () ist ein zufällig generierter Float, dessen 0.2 sein sollte.

Diese Aussage sollte also als 1 bewertet werden.

Meine Frage: ist es möglich, dass aufgrund eines Gleitkommafehlers NICHT zu 1 ausgewertet wird?

Wenn zum Beispiel aufgrund eines Gleitkommafehlers etwas 0.2 sein könnte, könnte das LESS sein? IE, betrachten Sie zum Beispiel die folgenden 3 Möglichkeiten:

%Vor%

Ist case3 sogar möglich ?, wobei 0.1999999999999999 das Ergebnis eines Gleitkommafehlers ist? Ich habe bisher noch nie ein negatives epsilon gesehen, nur Fall 2, wenn es ein bisschen größer ist, und das ist OK, wenn es in int () umgewandelt wird, das "floor" es zum richtigen Ergebnis. Bei einem negativen Epsilon wird der "flooring" -Effekt jedoch dazu führen, dass der resultierende Wert 0,9999999999999996 zu 0 wird.

    
Martin K 05.07.2012, 19:13
quelle

5 Antworten

3

Es ist unmöglich, dass myRandom .2 zurückgibt, weil .2 nicht als Float oder Double dargestellt werden kann, wenn Ihr Zielsystem den IEEE 754 Binary Floating-Point-Standard verwendet, der überwiegend der Standardwert ist.

Wenn myRandom () die darstellbare Zahl mit der nächstliegenden .2-Zahl zurückgibt, ist myInt gleich 1, da die als Float darstellbare Zahl .2 etwas größer als 0,2 ist (es ist 0,200000002980232238776953125) und auch das nächstgelegene darstellbare Double (0.20000000000000001110223024625156540423631668090820312).

In anderen Fällen wird dies nicht wahr sein. ZB ist das nächste Doppel zu .6 0,59999999999999977779553950749686919152736663818359375, also wird myInt 2 sein, nicht 3.

    
Eric Postpischil 05.07.2012, 19:25
quelle
1

Ja, das ist möglich, zumindest was die C-Norm betrifft.

Der Wert 0.2 kann nicht exakt in einem binären Gleitkommaformat dargestellt werden. Der von myRandom() zurückgegebene Wert liegt daher entweder geringfügig unter oder geringfügig über dem mathematischen Wert 0.2 . Der C-Standard erlaubt beide Ergebnisse.

Nun kann es gut sein, dass die IEEE-Semantik nur erlaubt, dass das Ergebnis etwas größer als 0.2 ist - aber der C-Standard erfordert keine IEEE-Semantik. Und zwar unter der Annahme, dass das Ergebnis so genau wie möglich aus dem Wert 0.2 abgeleitet wird. Wenn der Wert aus einer Reihe von Gleitkommaoperationen generiert wird, von denen jeder einen kleinen Fehler verursachen kann, könnte er leicht kleiner oder größer als 0.2 sein.

    
Keith Thompson 05.07.2012 19:19
quelle
1

Es ist kein Fließkomma Fehler , es ist die Art wie Gleitkomma funktioniert. Jeder Bruch, der nicht 1 / (Potenz von 2) ist, kann nicht genau dargestellt werden und wird entweder nach oben oder unten zur nächsten darstellbaren Zahl gerundet.

Sie können Ihren Code reparieren, indem Sie ihn mit einem kleinen Epsilon multiplizieren, das größer als eins ist, bevor Sie in Ganzzahl konvertieren.

%Vor%

Siehe Was jeder Informatiker über Gleitkommaarithmetik wissen sollte .

    
Mark Ransom 05.07.2012 19:23
quelle
0

Das ist möglich, abhängig von der gewählten Nummer. Um eine bestimmte Nummer zu überprüfen, können Sie sie immer mit hoher Genauigkeit ausdrucken: printf ("% 1.50f", 0.2)

    
user1494736 05.07.2012 19:52
quelle
0

Warum multiplizieren Sie Ihren Gleitkommawert nicht mit 5.0 und verwenden Sie dann die runde Funktion, um ihn richtig zu runden?

    
Void Star 05.07.2012 19:58
quelle

Tags und Links