2010-01-19 4 views
0

~ S'il vous plaît pardonnez-moi -AIDE - IEEE - 754 - extrait, normalisé, NAN, etc

  • J'ai eu un précédent appelé IEEE - 754 - trouver signbit, exposant, frac, normalisé, etc ..

Cependant, je n'avais pas enregistré mon NIC et je ne peux pas l'éditer. (donc le poste est fondamentalement mort pour moi) Quelqu'un peut-il le supprimer? Ma question est également sans réponse. Donc je poste ceci avec un code différent.

  • j'ai encore besoin de beaucoup d'aide ... alors s'il vous plaît DonT traiter ce post comme un doublon ...

J'ai trouvé peu de signe, peu d'exposant et mantisse ..

Qu'est-ce que dois-je tester pour trouver normalisé? si exp == 0?

Que dois-je tester pour l'infini? exp == 0xff et mantiassa == 0? Est-ce que le signe a quelque chose à voir avec ça?

Que dois-je tester pour trouver zéro? exp == 0 et mantisse == 0? Est-ce que le signe a quelque chose à voir avec ça?

Que dois-je tester pour trouver NAN? quelqu'un peut s'il vous plaît expliquer aussi simple que vous pouvez depuis que je suis juste un débutant! Dois-je appliquer d'autres masques?

  • Y at-il un ordre dans lequel je suis supposé accomplir ce que je veux?

C'est ce que j'ai jusqu'à présent.

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]) { 
    int HexNumber; 

    printf("IEEE- 754 \n"); 
    int a = 0x12345678; 
    unsigned char *c = (unsigned char*)(&a); 

    if (*c == 0x78) { 
     printf("\nlittle-endian\n"); 
    } else { 
     printf("\nbig-endian\n"); 
    } 

    printf("\n>"); 
    scanf("%x", &HexNumber); 
    printf("\n%#x",HexNumber); 

    bool negative = !!(HexNumber & 0x80000000); 
    int exponent = (HexNumber & 0x7f800000) >> 23; 
    int mantissa = (HexNumber & 0x007FFFFF); 

    printf("\nsignBit %d,", negative); 
    printf("expbits %d,", exponent); 
    printf("fractbits %#x,", mantissa); 

    return 0; 
} 

... et ceci est ma sortie - qui est ce que je veux:

IEEE - 754 

little-endian 

>C0000000 

0xc0000000 
signBit 1,expbits 128,fractbits 0, 

Répondre

0

Si vous utilisez la fonction C99 essayez fpclassify, qui renverra une énumération disant que si la valeur est NAN, Infinity etc, et frexp qui va diviser la valeur pour vous.

Si vous voulez rouler le vôtre, n'oubliez pas que les infinis et les zéros sont signés. Les NaN sont définis par un modèle de bits spécifique dans l'exposant, je crois, la mantisse donne des informations supplémentaires de façon non-standard.

À la lecture du draft standard:

  • Si l'exposant est nul et la mantisse est différente de zéro la valeur est denormal

  • Si l'exposant est nul et la mantisse est égale à zéro la valeur est (+/-) zéro

  • Si l'exposant est le maximum et la mantisse est égale à zéro la valeur est (+/-) l'infini

  • Si l'exposant est le maximum et la mantisse est différente de zéro la valeur est NAN

+0

la lecture du projet de norme est agréable. Mais, quand nous testons zéro, comment savons-nous si c'est un plus ou un moins? même avec l'infini? – Steller

+0

@Corey Il semble que la réponse d'Alok montre les bits dont vous avez besoin pour vérifier un flotteur. La valeur est '(-1)^[bit de signe] * le reste', donc si le bit de signe est défini, la valeur est négative. Le bit de signe utilisé est le même pour zéro et l'infini. –

2

Pourquoi ne pas vérifier vous-même?

#include <stdio.h> 

void extract (float x) { 
    union { 
     float value; 
     struct { 
      unsigned int frac : 23; 
      unsigned int exp : 8; 
      unsigned int sign : 1; 
     } fields; 
    } conv; 
    conv.value = x; 
    printf ("Value = %.3g,\tSign = %x,\tExp = %x,\tFrac = %x\n", x, conv.fields.sign, conv.fields.exp, conv.fields.frac); 
} 

int main() { 
    extract (1.0f);  // normal number 
    extract (1.0f/3.0f); // normal number 
    extract (0.0f);  // 0 
    extract (-0.0f); // -0 
    extract (1.0f/0.0f); // inf 
    extract (-1.0f/0.0f); // -inf 
    extract (0.0f/0.0f); // nan 
    extract (1.e-40f); // denormal 
    extract (-1.e-42f); // denormal 
    return 0; 
} 

Résultat:

Value = 1, Sign = 0, Exp = 7f, Frac = 0 
Value = 0.333, Sign = 0, Exp = 7d, Frac = 2aaaab 
Value = 0, Sign = 0, Exp = 0, Frac = 0 
Value = -0, Sign = 1, Exp = 0, Frac = 0 
Value = inf, Sign = 0, Exp = ff, Frac = 0 
Value = -inf, Sign = 1, Exp = ff, Frac = 0 
Value = nan, Sign = 0, Exp = ff, Frac = 400000 
Value = 1e-40, Sign = 0, Exp = 0, Frac = 116c2 
Value = -1e-40, Sign = 1, Exp = 0, Frac = 116c2 

Observation:

  • Si exp = 0xff, il est soit ± nan ou inf.
    • Si frac = 0, il s'agit de inf (+ ou -).
    • Si frac ≠ 0, il est nan (bit de signe n'a pas d'importance).
  • Si exp = 0, il s'agit de zéro ou de dénormal.
    • Si frac = 0, il vaut zéro (+ ou -).
    • Si frac ≠ 0, il est denormal (+ ou -).

Si vous utilisez C, il est déjà isnan, isinf/isfinite, isnormal et signbit dans <math.h> pour ces tests.

+0

Comment puis-je vérifier si le NAN est SNAN ou QNAN? – Steller

+0

Comment puis-je savoir si c'est plus ou moins? – Steller

+0

La signalisation/les NaNs silencieux sont spécifiques à l'implémentation Je crois que vous devrez regarder la valeur de Frac. Pour plus/moins, regardez la valeur du signe dans le résultat. –

2

En C99, vous pouvez utiliser fpclassify() et signbit() macros de math.h (projet C99, F.3):

La signbit macro et la fpclassify macro <math.h>, utilisé conjointement avec les macros de classification numérique (Fournissent les fonctions de classe recommandées dans l'appendice de la CEI 60559 (sauf que les macros de classification définies au 7.12.3 ne distinguent pas la signalisation des NaN silencieux).

Pour mettre en œuvre ces tests vous-même, vous pouvez utiliser quelque chose comme ceci (valable pour les valeurs flottantes, prises et modifiées à partir de sources glibc):

int my_fpclassify(uint32_t x) 
{ 
    x &= 0x7fffffff; 
    if (x == 0) 
     /* zero */ 
    else if (x < 0x800000) 
     /* subnormal */ 
    else if (x > 0x7f800000) 
     /* nan */ 
    else if (x == 0x7f800000) 
     /* inf */ 
    else 
     /* normal */ 
} 

int my_signbit(uint32_t x) 
{ 
    return x & 0x80000000; 
} 
+0

qu'est-ce que x dans ce cas? Est-ce le nombre à virgule flottante? – Steller

+0

x devrait être un flottant, il a été catalogué dans un int afin que les opérations de bits fonctionnent. –

+0

'x' est de type' uint32_t'. Il a été obtenu à partir d'une valeur à virgule flottante, après avoir fixé les «problèmes» d'endianisme. –

Questions connexes