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:
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.
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
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.
Tags und Links c type-conversion integer-overflow