Si j'écris :
int x = /* any non-zero integer value */;
float y = x;
float z = y / y;
Est z
garantie d'être exactement 1.f ?
Si j'écris :
int x = /* any non-zero integer value */;
float y = x;
float z = y / y;
Est z
garantie d'être exactement 1.f ?
Si votre implémentation C++ utilise IEEE754, alors oui, c'est garanti. (L'opérateur de division est nécessaire pour renvoyer la meilleure valeur possible en virgule flottante).
El uniquement exceptions pour y / y
en général, ne pas être 1.f
sont les cas où y
est NaN
, +Inf
, -Inf
, 0.f
y -0.f
ou si vous êtes sur une plateforme où int
est si large que certaines de ses instances ne peuvent pas être représentées dans une float
sans cela float
étant réglé sur +Inf
o -Inf
1 . En mettant de côté ce dernier point, dans votre cas, cela signifie que int x = 0;
produira la seule exception.
Le IEEE754 est extrêmement courant. Mais pour en être sûr, testez la valeur de
std::numeric_limits<float>::is_iec559;
1 Une plate-forme, par exemple, avec un système d'exploitation de 128 bits. int
et un IEEE754 32 bits float
présenterait ce comportement pour certaines valeurs de x
.
Non, pas dans tous les cas, même pour IEEE754.
Par exemple, avec int x = 0;
vous obtiendrez NaN. ( En direct )
J'ai trouvé votre formulation ambiguë et trompeuse, j'ai donc suggéré une modification pour la rendre plus claire.
@cat Je peux comprendre la partie "pas dans tous les cas" de votre suggestion, mais votre utilisation de "Par exemple" suggère qu'il y a d'autres valeurs pour lesquelles la même chose s'applique, et pour cette raison, personnellement, je pense que la réponse qui est ici maintenant est meilleure que la réponse que vous avez suggérée.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
8 votes
Il faudrait faire preuve d'une pédanterie inhabituelle, même selon les normes du C++, pour soutenir que
std::numeric_limits<int>::max()
pourrait être plus grande questd::numeric_limits<float>::max()
.2 votes
@MSalters Haha, j'ai pensé à inclure cela, mais j'ai décidé que c'était trop stupide. :)
1 votes
@MSalters : FWIW, pour la plupart
x
,static_cast<int>(y) != x
(si les deux sont en 32 bits), maisz
sera toujours égal à1.0f
sauf six == 0
car le nominateur et le dénominateur ont tous deux la même erreur d'arrondi.0 votes
Si deux nombres
x
yy
sont assez grandes et assez proches les unes des autres (sans être égales), alorsx/y
sera probablement1.f
également, en raison d'une erreur de conversion. Essayez de taper ceci dans la console de votre navigateur (qui utilise probablement aussi IEEE754) et appuyez sur ENTER :9223372036854775700/9223372036854775800
.1 votes
@ArneVogel : En fait, +INF/+INF est NaN, pas 1.0.
0 votes
@MSalters Dunno, cela semble être un point tout à fait valable ; c'est l'un des six ou sept cas dans lesquels le code ci-dessus ne renvoie pas
1f
.0 votes
Je me demande si un compilateur C++ pourrait optimiser cela et remplacer la division par une constante de 1.0f ?
0 votes
@StephenG Cela pourrait être le cas s'il utilise une approche d'optimisation de type "fast math", mais autrement, cela serait considéré comme un bug du compilateur, sauf s'il peut prouver que les cas d'exception ne vont pas se produire dans ce contexte particulier. Dans le code exact ci-dessus, où le programmeur spécifie la valeur de
x
comme un littéral, il est fort probable que tout compilateur un tant soit peu décent tentant de l'optimiser le réduise au résultat.0 votes
@MSalters : Maintenant tu dois juste montrer comment
y
peut être infini, si les deux types sont 32 bits. D'uh. Je commentais le cas de l'IEEE 754.0 votes
Je suppose que vous vouliez seulement poser la question sur le cas de
x != 0
... peut-être devriez-vous modifier la question en conséquence (malgré la réponse valide sur ce cas).