[C, C++] Difficoltà a capire gli operatori bitwise

oleg.fresi
Studiando c++ ho incontrato gli operatori bitwise che ho messo da parte per ritornarci più avanti. Ora che è arrivato il momento di farlo, sto trovando difficoltà nel capirli. Quello che ho capito è come funziona l'and a livello di bit, come funzione l'or, lo xor ecc, ma non riesco a capire come funzionano certi algoitmi che ne fanno uso. Per esempio non capisco perchè facendo l'and tra un numero e il suo precedente che viene 0, allora il numero è una potenza di 2. Non capisco davvero come si arrivi a questo risultato, come si dimostra? Potreste chiarirmi quest'ultimo e ingenerale darmi un consiglio su come capire questo genere di algoritmi?

Risposte
Obidream
"ZfreS":
In decimale è $22$. Ma perchè il mio codice non funziona?

Funziona, è che non sai perché e questo è un problema, il messaggio che ho quotato prima dell'edit era corretto, non so perché tu lo abbia cambiato.

oleg.fresi
Perchè prima avevo scritto, togliendo gli zeri prima: $11010000$ che è 208, mentre il 22 è $00010110$ , ma non funziona il codice, perchè invece di darmi $22$ mi da $208$. Come ho detto prima è come se facesse un semplice left shift.

vict85
"ZfreS":
Perchè prima avevo scritto, togliendo gli zeri prima: $11010000$ che è 208, mentre il 22 è $00010110$ , ma non funziona il codice, perchè invece di darmi $22$ mi da $208$. Come ho detto prima è come se facesse un semplice left shift.


Perché il circular shift è fatto su un intero da 32 bit e non sul singolo byte. Considera \((1\ll 28)\) e chiama la tua funzione con 7 e vedi che succede.

Tieni inoltre conto che stai lavorando con interi con segno.

oleg.fresi
Ora ho capito. In pratica il risultato è giusto perchè l'oprazione viene fatta sui 4 byte e non su uno. Ma se volessi "ignorare" gli altri 24 byte, come dovrei modificare il codice? Facendo riferimento al sito https://onlinetoolz.net/bitshift provando con il numero 13 e shift 3 viene 11, mentre con il mio codice viene(correttamente) 104

vict85
Dando una occhiata in giro ho trovato questo https://blog.regehr.org/archives/1063 che fornisce informazione su questo tipo di operazione. Riguardo alla versione con i byte. Direi che dovresti fare qualcosa come:

uint32_t ruota_byte(uint32_t x, uint32_t n)
{
   x &= 0xFF;
   n &= 7;
   return ( (x << n) | (x >> (-n&7)) ) & 0xFF;
}

Obidream
"ZfreS":
Facendo riferimento al sito https://onlinetoolz.net/bitshift provando con il numero 13 e shift 3 viene 11, mentre con il mio codice viene(correttamente) 104

Dal sito webbe:


00001101
Circular shift << 3
00011010
00110100
01101000
unsigned signed
hex 68 68
dec 104 104
oct 150 150
bin 1101000 1101000

oleg.fresi
Si, è così.

oleg.fresi
Ma se volessi farlo su un byte, cosa dovrei fare?

vict85
"ZfreS":
Ma se volessi farlo su un byte, cosa dovrei fare?


Guarda qualche messaggio fa, te l'ho già scritto.

oleg.fresi
Grazie mille vict!

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.