01: // analisi della rappresentazione interna di un float mediante union e operazioni bit a bit
02: #include<stdio.h>
03: #include<stdlib.h>
04: 
05: union mybits
06: {
07:   float        f;
08:   unsigned int u;
09: };  
10: // in una union tutti i dati sono sovrapposti
11: // visto che (per il nostro compilatore) float e unsigned int sono 
12: // entrambi 4 byte, si sovrappongono esattamente
13: 
14: int main(void) 
15: {
16: 
17:   union mybits x;
18: 
19:   printf("Inserisci un numero frazionario: ");
20:   scanf("%g", &x.f);   // leggo e scrivo dentro l'elemento f della union x
21:   // di fatto gli stessi bit di x.u
22: 
23:   unsigned sign     =  (x.u >> 31) & 0x1;                 // il bit piu' significativo e' il bit di segno
24:   unsigned exponent =  (x.u >> 23) & 0xFF;                // 8 bit di esponente
25:   unsigned mantissa =   x.u        & 0x7FFFFF;            // 21 bit di mantissa
26: 
27:   printf("value    : %f\n",  x.f);
28:   printf("raw bits : 0x%08x\n", x.u);
29:   printf("sign     : %u\n",  sign);
30:   printf("exponent : %u  (biased), %d (real)\n", exponent, (int)exponent - 127);
31:   printf("mantissa : 0x%06x\n", mantissa);
32: 
33:   return 0;
34: }
35: 
36: /* ESEMPIO DI ESECUZIONE
37: 
38: Inserisci un numero frazionario: -6.5
39: value    : -6.500000
40: raw bits : 0xc0d00000
41: sign     : 1
42: exponent : 129  (biased), 2 (real)
43: mantissa : 0x500000
44: 
45: SPIEGAZIONE 
46: 
47: Ricordiamoci che nel formato IEEE 794 il valore di quel float lo ricavo come
48: (scrivo l'elevazione a potenza usando '^' che in C significa tutt'altro...):
49: 
50: <bit di segno> * 1.<mantissa in binario> * 2 ^<exponent - 127> 
51: 
52: Nel nostro caso:
53: 
54: sign =  1           -> numero negativo
55: exponent real = 2   -> elevero' 2 alla 2 
56: mantissa = 0x500000 -> in binario 10100000000000 (perche' manca lo 0 iniziale?)
57: 
58: Quindi: -1 * 1.101 * 2^2 che fornisce esattamente -6.5
59: A rigore, dovevo scriverla totalmente in binario:
60: 
61: -1 * 1.101 * 10^10  tutte le basi sono base 10 ;)
62: 
63: 
64: */
65: 
66: 


Se avete commenti o osservazioni su questa pagina
mandate un messaggio di posta elettronica a bertoƶƶi@ce.unipr.it