Cercando di rispondere sia alla domanda esplicita (cos'è CHAR_BIT) sia alla domanda implicita (come funziona) nella domanda originale.
Un carattere in C e C ++ rappresenta la più piccola unità di memoria che il programma C può indirizzare *
CHAR_BIT in C e C ++ rappresenta il numero di bit in un carattere. Deve sempre essere almeno 8 a causa di altri requisiti sul tipo char. In pratica su tutti i moderni computer di uso generale è esattamente 8 ma alcuni sistemi storici o specialistici possono avere valori più alti.
Java non ha equivalenti a CHAR_BIT o sizeof, non ce n'è bisogno poiché tutti i tipi primitivi in Java sono di dimensioni fisse e la struttura interna degli oggetti è opaca per il programmatore. Se traduci questo codice in Java puoi semplicemente sostituire "sizeof (int) * CHAR_BIT - 1" con il valore fisso 31.
In questo particolare codice viene utilizzato per calcolare il numero di bit in un int. Tieni presente che questo calcolo presuppone che il tipo int non contenga bit di riempimento.
Supponendo che il tuo compilatore scelga di estendere il segno su spostamenti di bit di numeri con segno e supponendo che il tuo sistema usi la rappresentazione in complemento di 2 per i numeri negativi, ciò significa che "MASK" sarà 0 per un valore positivo o zero e -1 per un valore negativo.
Per negare un numero di complemento a due dobbiamo eseguire un no bit per bit e quindi aggiungerne uno. In modo equivoco possiamo sottrarne uno e poi negarlo bit per bit.
Anche in questo caso assumendo che la rappresentazione in complemento a due sia -1 è rappresentata da tutti, quindi esclusivo o con -1 è equivalente alla negazione bit per bit.
Quindi quando v è zero il numero viene lasciato solo, quando v è uno viene negato.
Bisogna tenere presente che l'overflow con segno in C e C ++ è un comportamento indefinito. Quindi l'utilizzo di questa implementazione ABS sul valore più negativo porta a un comportamento indefinito. Questo può essere risolto aggiungendo cast in modo tale che la riga finale del programma venga valutata in unsigned int.
* Che è solitamente, ma non in modo nesacerale, la stessa unità di memoria più piccola che l'hardware può indirizzare. Un'implementazione può potenzialmente combinare più unità di memoria indirizzabile tramite hardware in una unità di memoria indirizzabile tramite programma o dividere un'unità di memoria indirizzabile tramite hardware in più unità di memoria indirizzabile tramite programma.