Wenn ich schreibe:
int x = /* any non-zero integer value */;
float y = x;
float z = y / y;
Ist z
garantiert genau 1.f?
Wenn ich schreibe:
int x = /* any non-zero integer value */;
float y = x;
float z = y / y;
Ist z
garantiert genau 1.f?
x
, static_cast<int>(y) != x
(wenn beide sind 32-Bit), aber z
immer noch gleich sein, 1.0f
es sei denn , x == 0
weil beide Zähler und Nenner die gleiche Rundungsfehler haben.
x
und y
groß genug sind, und nahe genug zueinander (ohne gleich zu sein), dann x/y
wird wahrscheinlich 1.f
auch 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 / y
im allgemeinen nicht zu sein 1.f
sind die Fälle , in denen y
ist NaN
, +Inf
, -Inf
, 0.f
, und -0.f
, oder , wenn Sie auf einer Plattform, wo int
so breit ist , dass bestimmte Fälle können es nicht in a dargestellt werden , float
ohne dass float
zu seinem Satz +Inf
oder -Inf
1 . 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 int
und einem IEEE754 32 Bit float
würde dieses Verhalten für bestimmte Werte von zeigen x
.
y
dass NaN werden kann.
NaN
, von denen einige das Vorzeichenbit gesetzt haben. Aber wie NaN != NaN
für jedes Bitmuster von NaN ist es sinnlos zu streiten, ob "+ NaN == -NaN".
y
der 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?
float
nicht enthalten sein x
kann.
Nein, nicht in allen Fällen, auch nicht für IEEE754.
Mit erhalten Sie beispielsweise int x = 0;
NaN. ( Live )
inf
oder 0f
oder 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()
.