Pages: [1] 2   Go Down
Author Topic: decodificare complemento a due  (Read 982 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

volevo chiedere se c'è qualche comando specifico   in arduino per per trasformare in binario normale un numero  che
in origine   e a complemento a 2
Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21657
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Prendi il binario del numero in complemento a 2, lo inverti (cioè un bit ad 1 diventa 0 e viceversa) e poi ci sommi 1.
Logged


Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

volevo chiedere se c'è qualche comando specifico   in arduino per per trasformare in binario normale un numero  che
in origine   e a complemento a 2

Un valore in complemento a due è semplicemente un numero con valore negativo, è già in binario, se hai bisogno di convertirlo come valore positivo basta che lo moltiplichi per -1.
Logged

Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Prendi il binario del numero in complemento a 2, lo inverti (cioè un bit ad 1 diventa 0 e viceversa) e poi ci sommi 1.

ma non c'è un comado specifico bello e pronto?
Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

volevo chiedere se c'è qualche comando specifico   in arduino per per trasformare in binario normale un numero  che
in origine   e a complemento a 2

Un valore in complemento a due è semplicemente un numero con valore negativo, è già in binario, se hai bisogno di convertirlo come valore positivo basta che lo moltiplichi per -1.

ma se ho una serie di bit tipo   100110101000001010100011  se li trasformo viene fuori una schifezza  perche avendo il primo bit di sinistra a 1  aggiunge oltre due milioni alla cfra  quando il primo bit sta a significare solo il negativo,

che si fa?
Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21657
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ma non c'è un comado specifico bello e pronto?
Da dove ottieni questo numero in complemento a 2?

ma se ho una serie di bit tipo   100110101000001010100011  se li trasformo viene fuori una schifezza  perche avendo il primo bit di sinistra a 1  aggiunge oltre due milioni alla cfra  quando il primo bit sta a significare solo il negativo,

che si fa?
Che formato ha il numero? Lo hai come stringa, come array di char, come cosa? Per capire.
Logged


Cagliari, Italy
Online Online
Tesla Member
***
Karma: 104
Posts: 6626
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ma se ho una serie di bit tipo   100110101000001010100011  se li trasformo viene fuori una schifezza  perche avendo il primo bit di sinistra a 1  aggiunge oltre due milioni alla cfra  quando il primo bit sta a significare solo il negativo,

che si fa?

Leo ha già risposto.
Prendi il binario del numero in complemento a 2, lo inverti (cioè un bit ad 1 diventa 0 e viceversa) e poi ci sommi 1.

Prendi il tuo numero : 100110101000001010100011
lo inverti :                011001010111110101011100
e gli sommi 1:           011001010111110101011101
« Last Edit: October 26, 2012, 04:26:27 pm by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ma se ho una serie di bit tipo   100110101000001010100011  se li trasformo viene fuori una schifezza  perche avendo il primo bit di sinistra a 1  aggiunge oltre due milioni alla cfra  quando il primo bit sta a significare solo il negativo,

Mi sa tanto che non ti è molto chiara la rappresentazione dei valori negativi in binario, p.e. -1 diventa 255 con una codifica a 8 b it, 0b11111111, se lo guardi esclusivamente come valore a otto bit positivi, però se fai la conversione nel giusto modo diventa 1, il modo più rapido è moltiplicare il valore per -1, provare per credere.
Attenzione che se stai interpretando il valore binario che hai scritto come composto da un valore assoluto e l'ultimo bit come quello di segno stai sbagliando tutto.
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21657
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ma la domanda difatti è: da dove ha un numero in complemento a due?
Quella è una rappresentazione in memoria, lui non deve preoccuparsene di come i numeri sono memorizzati, ci pensa il compilatore a trattare i signed e gli unsigned nei modi appropriati.
Logged


Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ma la domanda difatti è: da dove ha un numero in complemento a due?

Ho fatto una piccola prova sul numero che ha fornito come esempio, è esattamente come pensavo io, lui lo interpreta come composto da un valore binario assoluto e l'ultimo bit che fa da segno, ovvero non ha capito il concetto di complemento a due e la rappresentazione dei valori negativi in binario  smiley
Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ma qui come facciamo a far distinguere ad arduino che se il 24°  bit  è uno   deve trattarlo come numero negativo
e fare la conversione e visualizzazione correttamente   (float per intenderci)

Dipende dal tipo dato, se uno char sono otto bit, se è un int sono 16 bit, se è un long int sono 32 bit, se è uno short long int sono 24 bit, non sono sicuro se Arduino supporta questo tipo di dato.
Però se è un float la cosa è molto diversa visto che non si usa il complemento a due per questa tipologia di valori, sono una rappresentazione del tipo mantissa con esponente e bit di segno, se il tuo dato è di questo tipo non può essere di solo 24 bit, per forza di cose deve essere a 32 bit (Arduino non tratta i double a 64 bit).
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21657
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Arduino non tratta i double a 64 bit
In realtà li tratta, basta specificare un tipo long long ed Arduino compila il codice e gestisce i numeri. Solo che non lo fa nativamente per cui si appesantisce il codice in maniera esorbitante.
Logged


Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

In realtà li tratta, basta specificare un tipo long long ed Arduino compila il codice e gestisce i numeri. Solo che non lo fa nativamente per cui si appesantisce il codice in maniera esorbitante.

E' vero che il tipo viene accettato dal compilatore, e ci mancherebbe che non lo fa visto che fa parte dello standard C, però sia il long long che il double, è la stessa identica cosa, vengono trattati come valori a 32 bit, ed è chiaramente scritto anche sul reference che è stato aggiornato da poco con la chiarificazione che sulla DUE il tipo dato è effettivamente da 64 bit.
Questa è una limitazione di tutti i compilatore per mcu a 8 bit, almeno in tutti quelli che mi è capitato di usare, perché è già molto oneroso gestire la matematica a 32 bit su questi micro, quella a 64 bit è proibitiva in termini di impegno cpu durante i calcoli, esistono librerie matematiche esterne al C standard che permettono di fare dei calcoli anche a 64 bit.
« Last Edit: October 27, 2012, 01:01:39 am by astrobeed » Logged

Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

allora   vediamo se riesco a venirne a capo  (sempre se è possibile)  

i dati vengono presi da un dispositiovo che misura,  il dispositivo puo inviare dati che vanno da 99999  a -99999  
le "certezze sono" il dispositivo   invia sempre 2 pacchetti da 24 bit  i dati giusti sono nel secondo pacchetto

arduino prende i dati tramite un pin interrupt  (clok del dispositivo)  e un altro pin  data del dispositivo

con questa riga di codice  


    
Code:
for(x=25; x<48; x++)  {  reading=reading+(data[x]*pow(2,x-25));
 

arduino li mette in fila e trova il numero decimale corrispondente (reading)

ora fino ache il numero inviato è positivo   tutto viene decodificato bene

quando invece il numero è negativo il dispositivo lo trasmette a complemento a 2

e reading  va a un numero oltre 2000000  perche il bit piu significativo e passato a uno


come faccio a d aggiustare la lettura del numero negativo?
sapendo che se reading assume un valore maggiore di un milione è sicuramente un numero negativo,

e se faccio Serialprint ( reading, BIN)  
"qualdo reading e maggiore di un milione"
 stampo il numero binario che in realta dovrebbe essere convertito da complemento a due a normale
quidi su questo numero binario  maggiore di un milione
andrebbe fatta la conversione (nello sketc ovviamente)

Prendi il tuo numero : 100110101000001010100011
lo inverti :                  011001010111110101011100
e gli sommi 1:             011001010111110101011101



Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Cagliari, Italy
Online Online
Tesla Member
***
Karma: 104
Posts: 6626
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Devi saltare la lettura dell'ultimo dato perché non fa parte del numero, ma indica solo il segno.
quindi per il primo pacchetto
Code:
for(x=24; x<47; x++)  {  reading1=reading1+(data[x]*pow(2,x-24));
e per il secondo:
Code:
for(x=0; x<23; x++)  {  reading2=reading2+(data[x]*pow(2,x));

Poi con un if moltiplichi il numero -1 in base al valore dell'ultimo bit.
Code:
if (data[47]==1) reading1 = reading1 * -1;
e
Code:
if (data[23]==1) reading2 = reading2 * -1;

Controlla il codice perché non ho verificato se è corretto e compila, ma la logica dovrebbe andare.
Forse puoi fare anche un
Code:
if (data[47]==1) reading1 != reading1;

EDIT:
Verifica gli indici perché non so se il tuo array in lettura parta da 0 o da 1.
Se parte da 0 i primi 24 bit vanno da 0 a 23. 0-22 i dati e 23 il segno. E il secondo gruppo da 24 a 47, 24-46 i dati e 47 il segno.
Viceversa se parte da 1 avrai da 1 a 24 il primo pacchetto con 1-23 i dati e 24 il segno e l'altro sarà da 25 a 48 con 25-47 di dati e il 48° il segno.
« Last Edit: October 27, 2012, 03:21:29 am by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Pages: [1] 2   Go Up
Jump to: