|
Una seconda versione della conversione. In questo caso si richiede la scrittura di una
funzione generalizzata. Viene esplicitamente richiesto che si usi una funzione di converisone da
binario a decimale che vada bene sia per la mantissa che per l'esponente.
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.
Si utilizzi un'unica funzione con opportuni parametri per tutte le conversioni da binario
a numero (usare un double anche per l'esponete, per generalità).
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
// Converte i bit in 'vet' da 'inizio' a 'fine' partendo dal peso massimo 'peso'
double conversione(double peso,int vet[],int inizio,int fine);
main()
{
double esp; // Esponente convertito
double mant; // Mantissa convertita
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");
esp=conversione(128,vet,1,8); // Converte esponente
mant=conversione(1,vet,9,31); // Converte mantissa
esp=esp-128; // Toglie offset ad esponente
mant=mant+2; // Aggiunge bit nascosto a mantissa
SegnMant(vet); // Stampa segno mantissa
printf("%f ",mant); // Stampa mantissa
printf(" * 2^ %f",esp); // tampa 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("-");
}
}
/* Conversione binaria generica:
* Converte il numero nel 'vettore di bit' 'vet', a partire dal bit vet[inizio]
* fino al bit vet[fine] compreso.
* Usa 'peso' come peso del bit piu' significativo.
* Ritorna un double, in modo da convertire anche numeri in virgola fissa
*/
double conversione(double peso,int vet[],int inizio,int fine)
{
int i; // Contatore dei bit
double c=0; // Risutlato
for(i=inizio;i<=fine;i++) // Loop sui bit indicati
{
c=c+peso*vet[i]; // Somma il bit corrente
peso=peso/2; // Aggiusta il peso per il prossimo
}
return c; // Restituisce il risultato
}
|
Per provare il programma, scaricare il sorgente, compilarlo
con il comando cc float2.c ed eseguirlo con il comando ./a.out.
[Home Page dell'ITIS "Fermi"]
[Indice Terza]
[Precedente]
[Successivo]
© Ing. Stefano Salvi - Released under GPL licence
|