Tratando de responder tanto la pregunta explícita (qué es CHAR_BIT) como la pregunta implícita (cómo funciona esto) en la pregunta original.
Un carácter en C y C ++ representa la unidad más pequeña de memoria que el programa C puede abordar *
CHAR_BIT en C y C ++ representa el número de bits en un char. Siempre debe ser al menos 8 debido a otros requisitos sobre el tipo de char. En la práctica, en todas las computadoras modernas de propósito general es exactamente 8, pero algunos sistemas históricos o especializados pueden tener valores más altos.
Java no tiene equivalente a CHAR_BIT o sizeof, no es necesario ya que todos los tipos primitivos en Java tienen un tamaño fijo y la estructura interna de los objetos es opaca para el programador. Si traduce este código a Java, simplemente puede reemplazar "sizeof (int) * CHAR_BIT - 1" por el valor fijo 31.
En este código en particular, se utiliza para calcular el número de bits en un int. Tenga en cuenta que este cálculo asume que el tipo int no contiene bits de relleno.
Suponiendo que su compilador elige firmar extender en cambios de bits de números con signo y asumiendo que su sistema usa representación de complemento a 2 para números negativos, esto significa que "MASK" será 0 para un valor positivo o cero y -1 para un valor negativo.
Para negar un número de complemento a dos, debemos realizar un not a nivel de bits y luego agregar uno. De manera equivalente, podemos restar uno y luego negarlo bit a bit.
Nuevamente, asumiendo que la representación del complemento a dos, -1 está representada por todos, por lo que exclusiva o con -1 es equivalente a la negación bit a bit.
Entonces, cuando v es cero, el número se deja solo, cuando v es uno, se niega.
Algo a tener en cuenta es que el desbordamiento firmado en C y C ++ es un comportamiento indefinido. Entonces, el uso de esta implementación de ABS en el valor más negativo conduce a un comportamiento indefinido. Esto se puede solucionar agregando conversiones de modo que la línea final del programa se evalúe en unsigned int.
* Que es generalmente, pero no necesariamente, lo mismo que la unidad más pequeña de memoria que el hardware puede abordar. Una implementación puede potencialmente combinar varias unidades de memoria direccionable por hardware en una unidad de memoria direccionable por programa o dividir una unidad de memoria direccionable por hardware en varias unidades de memoria direccionable por programa.