Atsortingbuer l’infini à flotter

J’essaye d’initialiser un float à la valeur infini, et sans utiliser la macro INFINITY.

float f[] = { 0b01111111100000000000000000000000, // 0x7f800000 0x7f800000 -1, 0x7f800000 -2, 0x7f800000 -64, 0x7f800000 -65 }; 

Imprimé:

 2139095040.000000 2139095040.000000 2139095040.000000 2139095040.000000 2139094912.000000 

Pourquoi la première donnée infinie (comme 1 / 0.0 ) et les autres ne changent pas avant la dernière donnée?

0x7f7fffff devrait être la plus grande valeur qu’un float puisse être et essayer ici 0x7f80000 est considéré comme un infini.

La raison de votre problème est les notations:

  • 0x7f800000
  • 0b01111111100000000000000000000000

Ces notations se rapportent au type int et lorsque vous affectez int à float cela signifie implicit conversion d’ int en float . Dans ce cas-ci, vos deux nombres sont 2139095040 en décimale et il sera converti au type float .

Pour éviter ce problème, vous pouvez atsortingbuer une valeur dans des positions de bits exactes de 4 octets. Voici quelques exemples.

 float f; *(int*)&f = 0x7f800000; 

Ou vous pouvez utiliser les syndicats

 union u_fi { float f; int i; } fi; fi.i = 0x7f800000; 

Mais soyez prudent lorsque vous utilisez ces 2 solutions. Cela ne fonctionnera pas en toute sécurité si int est supérieur à 4 octets dans le premier cas et ne fonctionnera pas du tout si int est big-endian . Donc, ces solutions dépendent de la plate-forme et il est recommandé d’utiliser une macro comme celle présentée ci-dessous.

Une autre solution à votre problème consiste à utiliser un très grand nombre qui convertit en float comme inf . Pour cela, vous pouvez utiliser une macro comme dans

 #define _HUGE_ENUF 1e+300 #define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) float f = INFINITY; 

Vous pouvez utiliser la macro HUGE_VAL. Ou, si vous préférez, vous pouvez initialiser une variable factice à zéro et la diviser par cette variable (pour éviter toute erreur de compilation).

En supposant que vous utilisiez IEEE754 (ce que votre question implique), vous pouvez obtenir un résultat qui déborderait. float ne peut représenter que des valeurs allant jusqu’à 3.4028235f38 , nous pourrions donc utiliser

 float x = 1e20f*1e20f; 

En fonction de votre système / compilateur, vous devrez peut-être spécifier des indicateurs (par exemple, c99 ou c11 fonctionneront) afin que x soit explicitement converti en float et non stocké en tant que précision intermédiaire supérieure.