Dubbi con il Bitwise.

Buon giorno a tutti.
Mi sto cimentando nella manipolazione dei bit, e con il C ho dei problemi a capire.
Vi spiego cosa voglio fare: ho una variabile di tipo byte e diciamo che la uso come flag, ogni singolo bit è un flag ed in base se è 0 o 1 dovrò far fare delle cose.
Quello che vorrei fare è shiftare (destra o sinistra non importa) la variabile ed analizzare cosa esce; in assembler (derivo da li...) bastava fare uno shift a destra ed analizzare il carry, quindi sapevi ogni singolo bit se era 0 o 1.
Come si può fare in C??
Grazie a chi volessa darmi una mano.

Per sapere se il bit b di x è settato (con 7 <= b <= 0):

if (x & (1 << b)) {
  ...
}

Per settarlo:

x |= (1 << b);

Per metterlo a 0:

x &= ~(1 << b);

Ma devi solo testare se il bit è a 0 o ad 1 ? ... il modo più veloce è il risultato della AND con tutti i bit che non ti interessano a 0 e quello che ti interessa a 1 ...

Nel reference trovi le apposite funzioni per il set, clear e read del singolo bit (sono delle macro e sono veloci).

Guglielmo

P.S.: mi sono sovrapposto con SukkoPera :smiley:

manolomao:
Quello che vorrei fare è shiftare (destra o sinistra non importa) la variabile ed analizzare cosa esce; in assembler (derivo da li...) bastava fare uno shift a destra ed analizzare il carry

cf = n & 1;
n >>= 1;

Grazie tutti.
Allora Sukkopera, posso fare un ciclo for per testarli tutti e 8 i bit? (da 0 a 7)
Claudio_FF, mi spieghi come funziona

cf = n & 1;
n >>= 1;

Scusa l'ignoranza....

E che problema c’è?

for (byte b = 0; b < 7; ++b) {
  // if di cui sopra
}

Come funziona il suggerimento di Claudio è facile da capire se leggi quanto ti ho postato io, ma è più lento e, sopratutto, ti fa perdere il valore della variabile.

Ottimo Sukkopera, grazie!!
E' proprio quello che non volevo fare, perdere il valore della variabile....
Grazie.
Lo provo e poi vi dico...

… ma perché NON usare le più leggibili bitRead() bitWrite(), bitSet() e bitClear() del “core” di Arduino? … fanno la stessa cosa dato che sono delle macro, ma sono più “parlanti:slight_smile:

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))

Guglielmo

Perché io personalmente non le conoscevo, ma è una buona idea, approvo!

Vero!!!
ciclo for

for (byte b=0;b<7;b++){if(bitRead(x, b)==1){....fai qualcosa}
                                 else{....fai altro}}

Potrebbe andare?
Avete altra forma più elegante per far ciò??

Va bene.

gpb01:
... ma perché NON usare le più leggibili bitRead() bitWrite(), bitSet() e bitClear() del "core" di Arduino? ... fanno la stessa cosa dato che sono delle macro, ma sono più "parlanti" :slight_smile:

Grande Guglielmo, ottimo, non le conoscevo neanche io!!!
Grazie!!!

manolomao:
Claudio_FF, mi spieghi come funziona

cf = n & 1;

n >>= 1;

È la simulazione di uno shift a destra con scorrimento nel carry (simulato con la variabile cf)