PDA

Visualizza la versione completa : [C++]Conversione di un numero Da Decimale a Binario in complemento a Due


Warioss
21-11-2015, 15:00
Salve a tutti ,sono un newbie nel mondo della programmazione e sto studiando a scuola il linguaggio di programmazione C + + .
Abbiamo da poco finito di studiare tutte le strutture di controllo del C + + ( quelle sequenziali , selettive(if,else,switch), iterative ( while,do-while,for) ) e siamo passati ai sottoprogrammi e abbiamo accennato da poco gli array . (non abbiamo fatto matrici , record e tutto quello che viene dopo ovviamente, quindi vi prego di usare solo le conoscenze che ho specificato di avere :mame:)

Detto questo mi è venuta la voglia di fare un programma che ,dato dall'utente un numero decimale e un riempimento del vettore tre 8 e 32 ( che sarebbero poi i bit) , fosse in grado di stampare a video la conversione del numero in Binario Puro , Modulo e Segno , Complemento a Uno , Complemento a Due.

Per Binario Puro , Modulo e Segno , Complemento a Uno ci sono riuscito :
26590

Mentre con Complemento a Due ho delle difficoltà ...

ad esempio :
il numero 5, per convertirlo in complemento a due dobbiamo per prima cosa rappresentarlo in binario (in questo esempio supponiamo di avere a disposizione 8 bit)
Tale rappresentazione del 5 verrà effettuato in questo modo: 0000 0101(5).
Se invertiamo i bit così che 0 diventa 1 e 1 diventa 0 la sequenza cambierà nel seguente modo 1111 1010.
A questo punto abbiamo ottenuto il complemento a uno del numero 5, per ottenere il complemento a due sommiamo 1, ottenendo quindi:
1111 1010 + 0000 0001 = 1111 1011 (-5).
Il risultato ottenuto è un numero binario che rappresenta il numero negativo -5 secondo il complemento a due.


Io ho problemi nel momento in cui bisogna sommare uno in binario ...
il codice che ho costruito è il seguente , so che è molto lungo , stupido e poco ottimizzato , ma come ho detto sono newbie al massimo ... quindi ho inserito dei commenti che vi facciano capire come funziona:


void ConvertitoreBinCompl2(convertitore bin,int r,int num){
//Se il numero è negativo lo rende positivo
if(num<0){
num=-num;
//Riempie il vettore di 0
for(int i=0;i<r;i++)
bin[i]=0;
//Carica il Vettore dei resti parziali del numero diviso 2 fino a quando il numero non si annulla (conversione in binario puro ma al contrario)
for(int i=0;num!=0;i++){
bin[i]=num%2;
num/=2;
}
//Scambia il bit 0 con 1 e viceversa ( conversione in complemento a uno ma al contrario)
for(int i=0;i<r;i++){
if(bin[i]==0)
bin[i]=1;
else
bin[i]=0;
}
//"Dovrebbe" sommare 1 in binario al complemento a 1 contenuto nel vettore dal passaggio precedente così da ottenere il complemento a 2 al contrario
for(int i=0;i>r;i++){
if(bin[r-i]==1)
bin[r-i]=0;
else
bin[r-i]=1;
}
if(bin[r-1]==0)
bin[r-1]=1;
//Stampa il vettore dalla fine all'inizio così da ottenere la conversione nel verso giusto del numero in complemento a 2
cout<<"\n\nIl numero in complemento a 2 e':";
for(int i=r-1;i>=0;i--)
cout<<"["<<bin[i]<<"]";
}

}


Credo che l'errore sia nella penultima parte :


for(int i=0;i>r;i++){
if(bin[r-i]==1)
bin[r-i]=0;
else
bin[r-i]=1;
}
if(bin[r-1]==0)

bin[r-1]=1;

Il risultato che ottengo è questo :
26591


Grazie in anticipo a chiunque voglia aiutare un nabbo all'avventura :D

Scara95
21-11-2015, 18:01
Ti basta tenere tutti gli 0 fino al primo 1 e poi cambiare gli altri partendo dal numero positivo:
00010100 -> 11101100

Comunque il tuo codice presenta diversi errori:
i>r è sempre falsa: 0 è verosimilmente sempre minore di r, al più è uguale.
Inoltre r-i inizia con r-0=r che è una cella oltre la fine.
Anche se tu avessi scritto correttamente i<r e r-i-1 l'algoritmo non sarebbe stato comunque corretto. Infatti partire dal bit più significativo è come supporre che ci sia un riporto ad ogni bit, mentre tu avrai riporto finché hai 1 e poi basta:

00010100 -> 11101011 + 1 -> 11101100

Warioss
21-11-2015, 19:02
Ti basta tenere tutti gli 0 fino al primo 1 e poi cambiare gli altri partendo dal numero positivo:
00010100 -> 11101100

Comunque il tuo codice presenta diversi errori:
i>r è sempre falsa: 0 è verosimilmente sempre minore di r, al più è uguale.
Inoltre r-i inizia con r-0=r che è una cella oltre la fine.
Anche se tu avessi scritto correttamente i<r e r-i-1 l'algoritmo non sarebbe stato comunque corretto. Infatti partire dal bit più significativo è come supporre che ci sia un riporto ad ogni bit, mentre tu avrai riporto finché hai 1 e poi basta:

00010100 -> 11101011 + 1 -> 11101100
Oddio che sbadato! hai ragione!


for(int i=1;i<r;i++){
if(bin[r-i]==1)
bin[r-i]=0;
else
bin[r-i]=1;
}
if(bin[r-1]==0)
bin[r-1]=1;

Ecco così è corretto però in effetti come hai detto tu ho constatato che anche correggendo ciò , comunque non ottengo ancora quello che mi serviva.

Quindi sto tentando di ragionare sul tuo consiglio ...

Ti basta tenere tutti gli 0 fino al primo 1 e poi cambiare gli altri partendo dal numero positivo:
00010100 -> 11101100
Appena riesco ad ottenere qualcosa lo posto

Warioss
21-11-2015, 19:29
Ok ci sono riuscito , ora funziona

void ConvertitoreBinCompl2(convertitore bin,int r,int num){
int posprimadiuno=0;
//Se il numerp è negativo lo rende positivo
if(num<0){
num=-num;
//Riempie il vettore di 0
for(int i=0;i<r;i++)
bin[i]=0;
//Carica il Vettore dei resti parziali del numero diviso 2 fino a quando il numero non si annulla (conversione in binario puro ma al contrario)
for(int i=0;num!=0;i++){
bin[i]=num%2;
num/=2;
}
//Converte il numero da Binario puro a Complemento a 2
for(int i=1;i<r;i++){
if(bin[i]==0)
bin[i]=1;
else
bin[i]=0;
}
cout<<"\n\nIl numero in complemento a 2 e':";
for(int i=r-1;i>=0;i--){
cout<<"["<<bin[i]<<"]";
}
}
}


Esempio:

http://i63.tinypic.com/4l29f7.png (http://i63.tinypic.com/4l29f7.png)

Grazie mille Scara95, alla prossima :ciauz::ciauz:

Loading