PDA

View Full Version : [C] Da numero binario a decimale


Very Hard
23-04-2007, 17:59
Ciao a tutti...
ho bisogno urgentemente di un vostro aiuto!! :mc:
Devo implementare in un programma in C una funzione che mi converta un qualsiasi numero binario inserito dall'utente in un numero decimale. Detto così sembrerebbe facile ma il brutto è che non mi è consentito l’uso della funzione "pow" o di altre funzioni per l’elevamento a potenza.
Come posso fare??? :confused:

Grazie a chiunque riesca ad aiutarmi

andbin
23-04-2007, 18:33
Devo implementare in un programma in C una funzione che mi converta un qualsiasi numero binario inserito dall'utente in un numero decimale. Detto così sembrerebbe facile ma il brutto è che non mi è consentito l’uso della funzione "pow" o di altre funzioni per l’elevamento a potenza.Non serve l'elevamento a potenza.
Innanzitutto immagino che l'utente inserisca una sequenza di caratteri '0' e '1'. Alla fine dell'input dovresti quindi avere una stringa composta da questi due caratteri.
Dichiari una variabile di tipo int o long (dipende da cosa ti serve) inizializzata a zero. Per ogni carattere 0/1 che hai nella stringa, devi prima semplicemente shiftare a sinistra il valore numerico (vedi operatore << ), quindi impostare il bit 0 (il meno significativo) a 0/1 in base alla cifra binaria.

Very Hard
23-04-2007, 18:44
Prima di tutto ti ringrazio per la risposta...
Allora mi ero dimenticato di dire che il numero inserito dall'utente sono costretto a memorizzarlo in un vettore che non è una stringa di caretteri, quindi, non posso utilizzare su questo vettore le funzioni di manipolazione delle stringhe (strcpy, strcat, ecc.)...
Aggiungo anche che i valori sono interi unsigned a 32 bit

Avresti qualche altro consiglio da darmi???

La funzione che devo implementare è questa:

unsigned int bin2dec(char binstr[32])

andbin
23-04-2007, 19:12
Prima di tutto ti ringrazio per la risposta...
Allora mi ero dimenticato di dire che il numero inserito dall'utente sono costretto a memorizzarlo in un vettore che non è una stringa di caretteri, quindi, non posso utilizzare su questo vettore le funzioni di manipolazione delle stringhe (strcpy, strcat, ecc.)...Non è detto ... dipende. E poi comunque che sia una sequenza di caratteri terminata dal nullo '\0' come inteso in "C" oppure no, cambia poco. Ti basta sapere il numero dei caratteri.
Per fare l'input che funzione hai usato?? fscanf(), fgets(), loop con getchar(), altro???

Aggiungo anche che i valori sono interi unsigned a 32 bitOk.

La funzione che devo implementare è questa:

unsigned int bin2dec(char binstr[32])Ok ma nota una cosa: quindi in input hai sempre 32 caratteri?? O anche di meno??

Black imp
23-04-2007, 19:12
scusa non capisco: dici che il numero dell'utente NON è memorizzato in un vettore stringa però l'intestazione della funzione che devi implementare riceve proprio un vettore stringa. :confused: se è così andbin ti ha già detto tutto, se no non capisco.

andbin
23-04-2007, 19:16
scusa non capisco: dici che il numero dell'utente NON è memorizzato in un vettore stringa però l'intestazione della funzione che devi implementare riceve proprio un vettore stringa. :confused: se è così andbin ti ha già detto tutto, se no non capisco.Il fatto di usare un array di char non necessariamente significa avere una stringa, così come normalmente (come convenzione) è intesa in "C" cioè una sequenza di caratteri terminata dal carattere nullo.

Black imp
23-04-2007, 19:31
Il fatto di usare un array di char non necessariamente significa avere una stringa, così come normalmente (come convenzione) è intesa in "C" cioè una sequenza di caratteri terminata dal carattere nullo.

si ok però il problema mi sembra già risolto no? se proprio si vogliono usare le funzioni sulle stringhe si schiaffa l'array in una stringa locale, se no si scandisce l'array - un for da 0 a LUNGARRAY-1 - e, come più o meno hai detto tu, per ogni carattere 0/1 si shifta - il primo shift è ridondante - un long int lo si mette in OR bit a bit con 0x01 o 0x00 in base all'if sul carattere '1' o '0'. se ci sono caratteri diversi si manda l'utente ad arare i campi ... :D

Very Hard
23-04-2007, 19:45
Allora ho deciso di mettere tutta la traccia per essere più chiaro:

- S'implementino alcune funzioni di conversione tra sistemi di numerazione in varie basi.

1) void dec2bin(unsigned int inp, char binstr[32])
Memorizza la rappresentazione binaria di inp nel vettore binstr.
Il bit meno significativo è memorizzato in binstr[0].
I valori di inp sono interi unsigned a 32 bit (ovvero limitati all'intervallo 0…232-1).

2) unsigned int bin2dec(char binstr[32])
Ha come valore di ritorno la rappresentazione decimale di binstr.
Il bit meno significativo è memorizzato in binstr[0].


Attenzione!
Il vettore di caratteri binstr NON è una stringa di caratteri, perché non è presente
il carattere di terminazione ‘\0’.
Quindi, non si possono utilizzare su questo vettore le funzioni di manipolazione delle
stringhe (strcpy, strcat, ecc.).
Qualsiasi implementazione alternativa verrà considerata errata.

NON è necessario (quindi altamente SCONSIGLIATO)
che l’input dei dati sia INTERATTIVO.

Requisiti fondamentali per la realizzazione delle funzioni di conversione:
1) non è consentito l’uso della funzione pow o di altre funzioni per
l’elevamento a potenza.
2) la dichiarazione delle funzioni deve rimanere inalterata.
3) la stampa a video del risultato finale deve riportare la posizione delle
cifre seguendo l’ordine MSB…LSB.
Esempio:
dec2bin(4) => 00000000000000000000000000000100
MSB LSB

71104
23-04-2007, 19:45
uhm uhm uhm :mbe:

la mia versione (non testata come al solito :p):


unsigned int bin2dec(char binstr[32])
{
unsigned int Result = 0;

int Index;
for (Index = 0; binstr[Index] && (Index < 32); Index++)
{
Result *= 2;
if ('1' == binstr[Index])
{
Result++;
}
else if ('0' != binstr[Index])
{
printf("errore fatale nel subsystem Win32 causato dal kernel che pero' non riesce a mostrare la schermata blu perche' il codice che la mostra e' corrotto: l'utente e' andato ad arare.\n");
return (unsigned int)-1;
}
}

return Result;
}

mi sono tenuto sul sicuro nello scrivere la condizione del for perché non ho capito come viene terminata la stringa... :wtf:

maulattu
23-04-2007, 20:15
mi sono tenuto sul sicuro nello scrivere la condizione del for perché non ho capito come viene terminata la stringa... :wtf:

credo con il carattere ASCII 0 --> '\0' :read:

Black imp
23-04-2007, 20:17
unsigned int bin2dec( char binstr[32] )

{
unsigned long int pippo=0;
int i;
int err=0;
for (i=0; i<32 && !err; i++)
{
pippo<<=1;
if ((binstr[i]-'0')==1)
pippo|=0x01;
else if ((binstr[i]-'0')==0)
;
else
err=1;
}

return pippo;

}



poi vedi tu se scrivere qualcosa nel caso err==1 o permettere di restituire il risultato parziale. tra l'altro dobbiamo fidarci del fatto che l'array sia inizializzato a zero in precedenza? altrimenti se l'utente mette un numero minore di 32 di caratteri è probabile che poi vengano letti caratteri diversi da 0 e 1 senza che questo sia un errore.

Black imp
23-04-2007, 20:18
credo con il carattere ASCII 0 --> '\0' :read:

ma se ha ripetuto 3 volte che non è una stringa! :read:

andbin
23-04-2007, 20:57
1) void dec2bin(unsigned int inp, char binstr[32])
Memorizza la rappresentazione binaria di inp nel vettore binstr.
Il bit meno significativo è memorizzato in binstr[0].
I valori di inp sono interi unsigned a 32 bit (ovvero limitati all'intervallo 0…232-1).

2) unsigned int bin2dec(char binstr[32])
Ha come valore di ritorno la rappresentazione decimale di binstr.
Il bit meno significativo è memorizzato in binstr[0].Ok, però voglio fare un appunto: la traccia deve averla scritta sicuramente un pivello .... perdonatemi .... ma uno che chiede di fare una conversione da stringa (e qui per stringa intendo nel modo più generale una sequenza di caratteri) a numero senza poter fare una validazione dei caratteri (perché la funzione non potrebbe segnalare l'errore al chiamate, visto come è dichiarata) e che per di più chiede di fare in modo che il bit meno significativo stia in binstr[0] (a sinistra), non può certamente essere definito diversamente. :p

Ecco una possibile implementazione:
unsigned int bin2dec(char binstr[32])
{
unsigned int v, i;
for (i = 0; i < 32; i++)
v = v << 1 | (binstr[31-i] == '1');
return v;
}

void dec2bin(unsigned int inp, char binstr[32])
{
int i;
for (i = 0; i < 32; i++, inp >>= 1)
binstr[i] = (inp & 1) + '0';
}4 righe nette per bin2dec e 3 per dec2bin .....

Very Hard
23-04-2007, 21:02
Ragazzi grazie per le risposte, ma incomincio ad avere un pò di confusione in testa :help:

:(

x 71104:

Ho provato il tuo listato ma credo sia sbagliato... mi restituisce sempre l'errore!

x Black imp:

Si l'array inizialmente viene inizializzato a 0... ma come posso fare l'input?? Va bene anche non interattivo! Comunque il tuo listato dovrebbe funzionare sicuramente?? Io l'ho provato ma quando vado in stampa mi restituisce sempre un valore diverso... mah credo che l'errore sia mio, forse nel printf :boh:

Very Hard
23-04-2007, 21:26
Ok, però voglio fare un appunto: la traccia deve averla scritta sicuramente un pivello .... perdonatemi .... ma uno che chiede di fare una conversione da stringa (e qui per stringa intendo nel modo più generale una sequenza di caratteri) a numero senza poter fare una validazione dei caratteri (perché la funzione non potrebbe segnalare l'errore al chiamate, visto come è dichiarata) e che per di più chiede di fare in modo che il bit meno significativo stia in binstr[0] (a sinistra), non può certamente essere definito diversamente. :p

Ecco una possibile implementazione:
unsigned int bin2dec(char binstr[32])
{
unsigned int v, i;
for (i = 0; i < 32; i++)
v = v << 1 | (binstr[31-i] == '1');
return v;
}

void dec2bin(unsigned int inp, char binstr[32])
{
int i;
for (i = 0; i < 32; i++, inp >>= 1)
binstr[i] = (inp & 1) + '0';
}4 righe nette per bin2dec e 3 per dec2bin .....


Andbin io il primo punto l'avevo fatto così:



void dec2bin(unsigned int inp, char binstr[32])
{

i=0;
while(i<32)
{
if((inp%2)==0)
{
binstr[32-1-i]=0;
}
else
{
binstr[32-1-i]=1;
}
inp=inp/2;
++i;
}

}


La tua al momento ho provato solo da decimale a binario e mi restituisce numeri sballati... se preferisci ti posto tutto il listato incluso il main così magari mi saprai dire sicuramente dove sbaglio....

sottovento
24-04-2007, 09:39
[QUOTE=andbin;16856195]Ecco una possibile implementazione:
unsigned int bin2dec(char binstr[32])
{
unsigned int v, i;
for (i = 0; i < 32; i++)
v = v << 1 | (binstr[31-i] == '1');
return v;
}

Inizializza v prima di usarla.

Very Hard
24-04-2007, 12:04
Cosa sbaglio??? :muro: :muro: :muro:

#include<stdio.h>

#define BIT 32

void dec2bin(unsigned int inp, char binstr[32]);
unsigned int bin2dec(char binstr[32]);


int i,j;
int b;

char binstr[BIT];


int main()
{

for(i=0;i<BIT;i++)
{
binstr[i]=0;
}


printf("Numero decimale: ");
scanf("%d",&b);

dec2bin(b,binstr);


for(j=0;j<BIT;j++)
{
printf("%d ",binstr[j]);
}


for(i=0;i<BIT;i++)
{
binstr[i]=0;
}


printf("\nNumero binario: ");
scanf("%d",&binstr);

bin2dec(binstr);

printf("%d ",binstr);
printf("\n");


}


void dec2bin(unsigned int inp, char binstr[32])
{
i=0;
while(i<BIT)
{
if((inp%2)==0)
{
binstr[BIT-1-i]=0;
} else {
binstr[BIT-1-i]=1;
}
inp=inp/2;
++i;
}

}


unsigned int bin2dec(char binstr[32])
{
int i;
unsigned int val;
for(i=0;i<32;i++);
if(binstr[i]=='1') val |= 1<<i;
return val;
}




Qualsiasi "bin2dec" delle vostre che vado a sostituire non mi restituisce mai il numero decimale.... sbaglio nella visualizzazione????

Black imp
24-04-2007, 13:00
Ragazzi grazie per le risposte, ma incomincio ad avere un pò di confusione in testa :help:

vuole dire che quando leggi il numero non inverti la posizione dei caratteri. guarda che se il bit meno significativo deve stare in posizione 0 vuol dire che se il numero messo dall'utente è 1101 lo devi memorizzare come 1011 nell'array.

71104
24-04-2007, 14:56
x 71104:

Ho provato il tuo listato ma credo sia sbagliato... mi restituisce sempre l'errore! l'ho appena testato da me aggiungendo un main e funge; mi fai un esempio di input che gli potrebbe arrivare? questo è il main che gli ho aggiunto:

int main()
{
int Index;
char Input[32];
for (Index = 0; Index < 32; Index++)
{
Input[Index] = getchar();
}
printf("%d\n", bin2dec(Input));
return 0;
}

andbin
24-04-2007, 18:25
Inizializza v prima di usarla.Assolutamente ragione!
L'inizializzazione l'ho lasciata ..... nella tastiera. :p (il codice era chiaramente untested).

Very Hard
25-04-2007, 11:13
Arrivati a questo punto allora credo che sono io l'impedito :) che non riesco a fare un inizializzazione decente....
Che mi dite di questa???


#include<stdio.h>

#define BIT 32

unsigned int bin2dec(char binstr[32]);


int i;
char binstr[BIT];


int main()
{

for(i=0;i<BIT;i++)
{
binstr[i]=0;
}

printf("\nNumero binario: ");
scanf("%d",&binstr);


bin2dec(binstr);


printf("%d\n", binstr);
printf("\n");

}



unsigned int bin2dec(char binstr[32])
{
unsigned int Result = 0;

int Index;
for (Index = 0; binstr[Index] && (Index < 32); Index++)
{
Result *= 2;
if ('1' == binstr[Index])
{
Result++;
}
else if ('0' != binstr[Index])
{
printf("errore fatale nel subsystem Win32 causato dal kernel che pero' non riesce a mostrare la schermata blu perche' il codice che la mostra e' corrotto: l'utente e' andato ad arare.\n");
return (unsigned int)-1;
}
}

return Result;
}


Dove sbaglio??
E in più potrei inizializzare la variabile senza un input interattivo?
Tipo così andrebbe bene??
char binstr[32]={0,1,0,1,0,1,0}

oppure sbaglierei anche così?

andbin
25-04-2007, 11:25
char binstr[BIT];

printf("\nNumero binario: ");
scanf("%d",&binstr);%d serve per prendere un valore intero (int), quindi non puoi passare l'indirizzo di un vettore di char!!!

Così sarebbe giusto!!
int val;
scanf("%d",&val);

Very Hard
25-04-2007, 11:39
%d serve per prendere un valore intero (int), quindi non puoi passare l'indirizzo di un vettore di char!!!

Così sarebbe giusto!!
int val;
scanf("%d",&val);


Un inizializzazione del genere andrebbe bene???

int val =1010101010;
scanf("%d",&val)


???

andbin
25-04-2007, 11:51
Un inizializzazione del genere andrebbe bene???

int val =1010101010;
scanf("%d",&val)No, il 1010101010 che hai scritto è un valore decimale (non è possibile specificare valori "literal" in binario, al massimo ottale o esadecimale).

Per essere molto chiari: a te cosa serve avere in input:
- Una variabile intera
- Un vettore di char con dentro valori 0, 1
- Un vettore di char con dentro caratteri '0', '1'
?

Very Hard
25-04-2007, 12:21
Purtroppo io ho a disposizione solo la traccia che ho mostrato precedentemente e devo interpretarla... credo comunque che in input mi serva "Un vettore di char con dentro valori 0, 1"

andbin
25-04-2007, 12:25
Purtroppo io ho a disposizione solo la traccia che ho mostrato precedentemente e devo interpretarla... credo comunque che in input mi serva "Un vettore di char con dentro valori 0, 1"Allora se intendi valori 0/1, come inizializzazione:
char bits[BIT] = { 0, 1, 0, 1, 0 ....... };

Very Hard
25-04-2007, 12:58
Perfetto, e adesso come faccio a trasferire il valore contenuto in "char bits" alla funzione dec2bin per essere trasformato in valore decimale???
Grazie

andbin
25-04-2007, 20:37
Perfetto, e adesso come faccio a trasferire il valore contenuto in "char bits" alla funzione dec2bin per essere trasformato in valore decimale???Alla bin2dec, forse volevi dire ...

Comunque bits è un array, ti basta passare semplicemente bits alla funzione (passi cioè l'indirizzo dell'array). E nota bene: nel tuo post #21 hai scritto la bin2dec per gestire dei caratteri '0'/'1' (così come ho fatto io per le funzioni che ho messo nel post #13). Chiaramente se nell'array hai solo dei valori decimali 0/1, devi cambiarla.

Very Hard
26-04-2007, 11:19
Alla bin2dec, forse volevi dire ...

Comunque bits è un array, ti basta passare semplicemente bits alla funzione (passi cioè l'indirizzo dell'array). E nota bene: nel tuo post #21 hai scritto la bin2dec per gestire dei caratteri '0'/'1' (così come ho fatto io per le funzioni che ho messo nel post #13). Chiaramente se nell'array hai solo dei valori decimali 0/1, devi cambiarla.



Si scusa, volevo dire "bin2dec"...