Wenn ich schreibe:
int x = /* any non-zero integer value */;
float y = x;
float z = y / y;
Ist zgarantiert genau 1.f?
Wenn ich schreibe:
int x = /* any non-zero integer value */;
float y = x;
float z = y / y;
Ist zgarantiert genau 1.f?
x, static_cast<int>(y) != x(wenn beide sind 32-Bit), aber zimmer noch gleich sein, 1.0fes sei denn , x == 0weil beide Zähler und Nenner die gleiche Rundungsfehler haben.
xund ygroß genug sind, und nahe genug zueinander (ohne gleich zu sein), dann x/ywird wahrscheinlich 1.fauch aufgrund eines Fehlers bei der Umwandlung. Geben Sie dies in die Konsole Ihres Browsers ein (die wahrscheinlich auch IEEE754 verwendet) und drücken Sie die EINGABETASTE : 9223372036854775700/9223372036854775800.
Antworten:
Wenn Ihre C ++ - Implementierung IEEE754 verwendet, ist dies garantiert. (Der Divisionsoperator muss den bestmöglichen Gleitkommawert zurückgeben.)
Die einzigen Ausnahmen für y / yim allgemeinen nicht zu sein 1.fsind die Fälle , in denen yist NaN, +Inf, -Inf, 0.f, und -0.f, oder , wenn Sie auf einer Plattform, wo intso breit ist , dass bestimmte Fälle können es nicht in a dargestellt werden , floatohne dass floatzu seinem Satz +Infoder -Inf1 . Wenn Sie diesen letzten Punkt beiseite lassen, bedeutet dies in Ihrem Fall, dass dies int x = 0;die einzige Ausnahme darstellt.
IEEE754 ist extrem verbreitet. Aber um sicherzugehen, testen Sie den Wert von
std::numeric_limits<float>::is_iec559;
1 Eine Plattform mit beispielsweise 128 Bit intund einem IEEE754 32 Bit floatwürde dieses Verhalten für bestimmte Werte von zeigen x.
ydass NaN werden kann.
NaN, von denen einige das Vorzeichenbit gesetzt haben. Aber wie NaN != NaNfür jedes Bitmuster von NaN ist es sinnlos zu streiten, ob "+ NaN == -NaN".
yder Wert befand sich sowohl in einem Register als auch im Speicher, und der Compiler hat den Nenner aus dem Speicher geladen. Sie landen also bei y_from_register / y_from_memory. Wenn das Register eine höhere Genauigkeit als der Speicher hat, was ist die Garantie dafür, dass 1 das beste Teilungsergebnis ist?
floatnicht enthalten sein xkann.
Nein, nicht in allen Fällen, auch nicht für IEEE754.
Mit erhalten Sie beispielsweise int x = 0;NaN. ( Live )
infoder 0foder Varianten von diesen signiert, dann ist das Ergebnis auch nicht1f
std::numeric_limits<int>::max()dies größer sein könnte alsstd::numeric_limits<float>::max().