Konvertiere INT_MAX in float und dann zurück in Integer.

8

In der C-Programmierung finde ich ein seltsames Problem, das meiner Intuition entgegensteht. Wenn ich ein integer als INT_MAX ( 2147483647 , definiert in den limits.h) deklariere und es implizit in einen float -Wert umwandle, funktioniert es gut, dh der Float-Wert ist der gleiche wie der maximale Integer . Und dann wandle ich den float zurück in eine ganze Zahl, etwas Interessantes passiert. Das neue integer wird zur minimalen Ganzzahl ( -2147483648 ).
Die Quellcodes sehen wie folgt aus:

%Vor%

Ich bin mir nicht sicher, was passiert, wenn die Gleitkommazahl b in die Ganzzahl a_new konvertiert wird. Gibt es also eine vernünftige Lösung, um den maximalen Wert zu finden, der zwischen integer und float type hin- und hergeschaltet werden kann?

PS: Der Wert von INT_MAX - 100 funktioniert einwandfrei, aber das ist nur eine willkürliche Lösung.

    
houtoms 02.05.2014, 04:32
quelle

1 Antwort

10

Diese Antwort geht davon aus, dass float ein IEEE-754 Float mit einfacher Genauigkeit ist, das als 32-Bit codiert ist, und dass int 32-Bit ist. In diesem Wikipedia-Artikel finden Sie weitere Informationen zu IEEE-754.

Fließkommazahlen haben nur 24 Bits Genauigkeit, verglichen mit 32 Bits für einen int. Daher haben int-Werte von 0 bis 16777215 eine exakte Darstellung als Fließkommazahlen, aber Zahlen größer als 16777215 müssen nicht unbedingt exakte Darstellungen als Gleitkommazahlen haben. Der folgende Code demonstriert diese Tatsache (auf Systemen, die IEEE-754 verwenden).

%Vor%

Die erwartete Ausgabe ist

%Vor%

Von Interesse ist hier, dass der float -Wert 0x4b800002 verwendet wird, um die drei int -Werte 16777219, 16777220 und 16777221 darzustellen, und 16777219 in ein float umwandelt und zurück in ein int nicht beibehalten wird der genaue Wert von int .

Die beiden Gleitkommawerte, die INT_MAX am nächsten sind, sind 2147483520 und 2147483648, die mit diesem Code demonstriert werden können

%Vor%

Die interessanten Teile der Ausgabe sind

%Vor%

Beachten Sie, dass alle 32-Bit int -Werte von 2147483584 bis 2147483647 auf einen float -Wert von 2147483648 aufgerundet werden. Der größte int -Wert, der abgerundet wird, ist 2147483583, was dem (INT_MAX - 64) entspricht. auf einem 32-Bit-System.

Daraus könnte man schließen, dass Zahlen unter (INT_MAX - 64) sicher von int nach float und zurück nach int konvertieren. Das gilt jedoch nur für Systeme, bei denen die Größe eines int 32 Bits beträgt und ein float gemäß IEEE-754 codiert ist.

    
user3386109 02.05.2014, 07:46
quelle