2012-02-15 1 views
1

Ma question concerne les numéros IEEE 754 mono-percussion. Supposons que j'ai un struct:Struct to IEEE754

typedef struct __ieee754 
{ 
    int sign; 
    int exponent; 
    int mantissa; 
} IEEE754,*pIEEE754; 

Puis-je convertir en un seul percision (08/01/23 flottant) numéro? J'utilise C.

+2

L'identificateur '__ieee754' (tous les identificateurs commençant par' __') est réservé à l'implémentation. Je suggère que vous utilisiez un autre nom pour le bien de la portabilité. – pmg

Répondre

4

Supposant votre implémentation utilise les numéros de simple précision IEEE 754 pour float, quelque chose comme cela devrait fonctionner

struct __ieee754 f; 
/* set f to something valid */ 
float x = f.sign * f.mantissa * pow(2, f.exponent); 
+4

'ldexpf (f.mantissa, f.exponent)' pourrait être une meilleure idée que 'f.mantissa * pow (2, f.exponent)' –

3

En supposant 32 bits unsigned int et le type IEEE-754 simple précision float:

union bla { 
    unsigned int a; 
    float b; 
}; 

union bla num = { 
     (((unsigned int) f.sign & 1) << 31) 
     | (((unsigned int) f.exponent & 0xFF) << 23) 
     | ((unsigned int) f.mantissa & 0x7FFFFF); 
}; 

printf("%f\n", num.b) 
+1

Je n'ai pas downvote, mais vos décalages et masques pour l'exposant et la mantisse sont éteints Et vous ne pouvez pas l'assigner à un 'float'. Vous devez passer les bits via une «union» ou quelque chose de ce genre. – Mysticial

+0

On y va! +1 maintenant. – Mysticial

+0

@Mystical oui, de nombreuses erreurs dans la première version, merci pour la remarque. – ouah

3

L'une des deux réponses précédentes doit être incorrecte, car la question est sous-spécifiée. Nous devons savoir si la structure contient la représentation binaire des composants flottants IEEE ou si elle contient une définition numérique.

Basé sur le fait qu'ils sont des nombres entiers, la première est plus probable: -4,2 serait représenté comme {1,0x81,0x066666} ou 0xC0866666. Dans ce cas, la réponse de @ ouah est correcte, et @ pmg donnera 2.85e44. Par contre, pour que le code de @ pmg soit correct, la structure de -4.2 devrait être stockée sous {-1,-21,0x433333}. Et puis l'application de l'algorithme de @ ouah donne 0xF5C33333 qui est -4.9489e32 lorsqu'il est interprété comme un flottant IEEE.

Si nous supposons que vous utilisez la première représentation, il y a une astuce de processeur non portable qui peut simplifier votre code. Redéfinissez votre structure en tant que syndicat comme suit.

union flt { 
    struct ieee754 { 
     unsigned int mantissa:23; 
     unsigned int exponent:8; 
     unsigned int sign:1; 
    } raw; 
    float f; 
} 

(Vous pourriez avoir besoin d'inverser l'ordre des arguments en fonction de votre procesor - et assurer l'emballage est correct - c'est la partie non-portable)

Maintenant, votre code peut écrire directement à la mémoire bits et le relire comme flottants:

union flt num; 
    num.raw.sign = 1; 
    num.raw.exponent = 129; 
    num.raw.mantissa = 0x66666; 
    printf("%f", num.f); //prints 4.2 
+0

+1, personnellement pour des raisons de portabilité J'ai tendance à toujours éviter les champs de bits (presque tout est défini par l'implémentation lorsque je traite des champs de bits) mais vous avez de bons points dans votre réponse. – ouah