|
Dopo la spiegazione teorica della codifica in virgola mobile, si fà sperimentare
agli studenti la codifica dei numeri float.
Il testo dell'esercizio è il seguente:
Scrivere un programma C che legga da tastiera numeri in virgola mobile, float, e ne
stampi la rappresentazione binaria.
Il programma dovrà continuare a chiedere numeri in virgola mobile e stampare i risultaiti,
fino a chè l'utente non preme un certo testo.
Analizzare il formato del numero, eseguendo una serie di esperimenti e scrivere una serie
di funzioni per stampare i valori componenti del numero.
Note
- Per analizzare un numero float occorre prima immagazzinarlo in un
unsigned, che siamo in grado di converire. Per fare questo dobbiamo passare attraverso
i puntatori e l'operazione di type cast. Dovremo:
- Ottenere un puntatore al float con l'operatore &
- Cambiare il tipo del puntatore tramite il type cast ad unsigned *
- Ottenere il valore intero dell'immagine tramite l'operatore *
L'operazione complessivamente potrebbe essere eseguita così :
i = *(unsigned int *)&f;
- Per convertire un numero a partire dal bit più significativo è possibile:
- utilizzare una variabile con il peso
- inizializzarla al peso del bit più significativo
- moltipolicare il peso per il bit corrente e sommarlo al numero convertito
- Dividere il peso per 2, per ottenere il peso del bit successivo
- Passare al bit successivo e ricominciare da 3 finchè ci sono bit
Una possibile soluzione è la seguente:
// Tizio - Pinco - 3AIN - 08/02/02
// Rappresentazione binaria di un float
#include <stdio.h>
#define DIM 32 // Dimensione in bit di un float
void binario(unsigned b,int vett[],int dim); // Prende il numero 'b' di 'dim' bit e lo
// converte in 'vett'
void SegnMant(int vett[]); // Visualiza il segno della mantissa
void mantissa(int vett[]); // Visualizza la mantissa
void esponente(int vett[]); // Visualizza l'esponente
main()
{
int vet[DIM]; // Vettore nel quale immagazzinare il numero
unsigned i; // Rappresentazione binaria del float
float f; // Float letto
char m; // Carattere per fine ciclo
do{
printf("\n\nNumero: "); scanf("%f",&f); // Legge un float da tastiera
if(f==0.000000) // Se il float e' 0
{
printf(" 0.000000 * 2^ 000000"); // Stampa convenzionalemnte 0
} else {
i = *(unsigned int *)&f; // Trasferisce il float nell'unsigned
binario(i,vet,DIM); // Converte l'immagine in binario
printf("\n");
SegnMant(vet); // Stampa il segno della mantissa
mantissa(vet); // Stampa la mantissa
esponente(vet); // Stampa l'esponente
}
printf("\nEsc per terminare:\n");
m=getchar(); // Pausa e ripetizione
}while (m != 27); // Finche' non si preme 'esc'
}
/* converte un intero in binario
*
* Converte l'intero 'b' di dimensione 'dim' bit nel vettore 'vett',
* un bit per elemento, il bit piu' significativo nel primo elemento
* Alla fine stampa il risultato della conversione
*/
void binario(unsigned int b, int vett[],int dim)
{
int j; // Contatore per il ciclo
for (j=0; j< dim; j++) // memorizzazione a partire dall'ultimo
{ // elemento del vettore
vett[dim-1-j]=b%2; // resto della divisione
b=b/2; // quoziente della divisione
}
// Visualizzazione
for(j=0;j<dim;j++)
{
printf("%d",vett[j]);
}
}
/* visualizza il segno della mantissa
*
* Il segno della mantissa e' immagazzinato nel bit piu' significativo.
* Il valore 0 indica segno positivo
*/
void SegnMant(int vett[])
{
if(vett[0] == 0)
{
printf("+");
} else {
printf("-");
}
}
/* visualizza la mantissa
*
* La mantissa occupa gli ultimi 22 bit del numero, vale a dire dal 9 al 31
* Il bit piu' significativo (nascosto) vale 2. Il numero e' immagazzinato
* come modulo/segno. Il segno e' gia' stato stampato, qui si stampa il modulo
*/
void mantissa(int vett[])
{
int i=0; // Contatore
float peso=1; // Peso del bit
float dec=2; // Risultato, inizializzato con il bit nascosto
for(i=9;i<DIM;i++) // Partendo dal piu' significativo fino alla fine
{
dec=dec+vett[i]*peso; // Moltiplica il bit per il peso e lo agginge al numero
peso=peso/2; // Divide il peso per passare la prossimo bit
}
printf("%f",dec); // Stampa il risultato
}
/* visualizza l'esponente
*
* L'esponente e'immagazzinato nei bit dal secondo al nono (quindi 8 bit)
* con codifica 'offset 128'
*/
void esponente(int vett[])
{
int i; // Indice del ciclo
int p=128; // Peso inizializzato al bit piu' significativo
int esp=0; // Esponente convertito
for(i=1;i<=8;i++) // Dal bit 1 all'8
{
esp=esp+vett[i]*p; // Aggiunge il bit corrente con il suo peso
p=p/2; // Calcola il nuovo peso
}
esp-=128; // Toglie l'offset
printf(" * 2^ %d\n",esp); // Stampa il risultato
}
|
Per provare il programma, scaricare il sorgente, compilarlo
con il comando cc float.c ed eseguirlo con il comando ./a.out.
[Home Page dell'ITIS "Fermi"]
[Indice Terza]
[Precedente]
[Successivo]
© Ing. Stefano Salvi - Released under GPL licence
|