3 progs d'opérations sur des floats, réalisés par masquage sur linux

Contenu du snippet

But : se faire une idée du codage des floatants en C.
prog 1 : renvoie les champs signe, exposant et mantisse d'un float
prog 2 : récupère la partie entière d'un float et la place dans un int
prog 3 : renvoie le flotant a partir des champs signe,exposant et mantisse

Source / Exemple :


/***************************************************************

  • Petit Rappel pour comprendre la suite : *
  • Float = (-1)^S * 2^(E-127) * 1,(M base2) * * Float (32bits), Signe (1bit), Exposant (8bits), Mantisse (32bits) *
                                                                                                                              • /
/***************************************************************
  • Prog1: *
  • Renvoie les champs signe, exposant et mantisse * * *
                                                                                                                              • /
#include <stdio.h> #define MASKsigne 0x80000000 #define MASKexposant 0x7F800000 #define MASKmantisse1 0x00FFFFFF #define MASKmantisse2 0x00800000 void separeFloat(float x, char *signe, char *exposant, unsigned long int *mantisse); int main(void) { float reel; char sigreel; char expreel; unsigned long int manreel; printf("Saisir un reel : "); scanf("%f", &reel); separeFloat(reel, &sigreel, &expreel, &manreel); printf("Signe \t\t(%d)\nExposant \t(%d)\nMantisse \t(%x)\n",sigreel, expreel, manreel); return 0; } void separeFloat(float x, char *signe, char *exposant, unsigned long int *mantisse) { unsigned long *ptIntX; ptIntX = (unsigned long*) &x; /* Sauvegarde du signe */
  • signe = (*ptIntX & MASKsigne) >> 31;
/* Sauvegarde de l'exposant */
  • exposant = ((*ptIntX & MASKexposant) >> 23) - 0x7F;
/* Sauvegarde de la mantisse */
  • mantisse = (*ptIntX & MASKmantisse1) | MASKmantisse2;
} /***************************************************************
  • Prog2: *
  • Récupère la partie entière d'un float et la place dans un int * * *
                                                                                                                              • /
#include <stdio.h> #define MASKsigne 0x80000000 #define MASKexposant 0x7F800000 #define MASKmantisse1 0x007FFFFF #define MASKmantisse2 0x00800000 signed int convFloatToInt(float x,char *erreur); int main(void) { float reel; signed int entiersign; char erreur; printf("Saisir un reel : "); scanf("%f", &reel); entiersign = convFloatToInt(reel, &erreur); if (erreur=='0') { printf("La partie entiere du reel est :\n"); printf("%d\n", entiersign); } else printf("Le reel saisie est trop grand : il ne rentre pas dans la representation des entiers.\n"); entiersign = reel; printf("%d\n",entiersign ); return 0; } signed int convFloatToInt(float x,char *err) { unsigned long* ptIntX; unsigned long int mantisse; char signe; char exposant; signed int res; ptIntX = (unsigned long *) &x; signe = (*ptIntX & MASKsigne) >> 31; exposant = ((*ptIntX & MASKexposant) >> 23) - 0x7F; mantisse = (*ptIntX & MASKmantisse1); if (exposant <= 31) { if (exposant != -0x7F) { if (signe==0x01) { res = ~((((*ptIntX & MASKmantisse1) | MASKmantisse2) << 8 ) >> (31-exposant))+1; } else { res = (((*ptIntX & MASKmantisse1) | MASKmantisse2) << 8 ) >> (31-exposant); } } else res = 0;
  • err = '0';
} else {
  • err = '1';
} return res; } /***************************************************************
  • Prog3: *
  • Renvoie le flotant a partir des champs signe,exposant et mantisse * * *
                                                                                                                              • /
#include <stdio.h> #define MASKsigne 0x80000000 #define MASKexposant 0x7F800000 #define MASKmantisse1 0x00FFFFFF #define MASKmantisse2 0x00800000 #define MASKsigneR 0x00000001 #define MASKexposantR 0x000000FF #define MASKmantisseR 0x007FFFFF typedef struct{ char chS; unsigned char chE; unsigned long int chM; }champsFloat_T; void separeFloat(float x, char *signe, char *exposant, unsigned long int *mantisse); float recontriutFloat(champsFloat_T sFloat); int main(void) { float reel; char sigreel; char expreel; unsigned long int manreel; champsFloat_T Recup; float reel2; printf("Saisir un reel : "); scanf("%f", &reel); separeFloat(reel, &sigreel, &expreel, &manreel); printf("Signe \t\t(%d)\nExposant \t(%d)\nMantisse \t(%x)\n",sigreel, expreel, manreel); Recup.chS = sigreel; Recup.chE = expreel; Recup.chM = manreel; reel2 = recontriutFloat(Recup); printf("Le reel recalcule est : %f\n",reel2); return 0; } void separeFloat(float x, char *signe, char *exposant, unsigned long int *mantisse) { unsigned long *ptIntX; ptIntX = (unsigned long*) &x; /* Sauvegarde du signe */
  • signe = (*ptIntX & MASKsigne) >> 31;
/* Sauvegarde de l'exposant */
  • exposant = ((*ptIntX & MASKexposant) >> 23) - 0x7F;
/* Sauvegarde de la mantisse */
  • mantisse = (*ptIntX & MASKmantisse1) | MASKmantisse2;
} float recontriutFloat(champsFloat_T sFloat) { unsigned long *ptIntH; float flotant; ptIntH = (unsigned long*) &flotant;
  • ptIntH = (((sFloat.chM) & MASKmantisseR ) | (((sFloat.chE) + 0x7F ) << 23)| ((sFloat.chS) << 31 ) ) ;
return flotant; }

Conclusion :


Normalement, il ne devrait pas y avoir de bug. Je m'exuse néanmois pour le style de commentaire fantaisiste, si quelqu'un veut une explication, qu'il laisse un commentaire.

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.