Gama de caracteres firmados

¿Por qué el rango de caracteres con signo es de -128 a 127 pero no de -127 a 128 ?

Esto se debe a la forma en que funciona la encoding del complemento de dos : 0 se trata como un número “positivo” (bit con signo desactivado), por lo tanto, el número de valores positivos disponibles se reduce en uno.

En la encoding de complemento de One (que no es muy común hoy en día, pero en los tiempos pasados, lo era), había valores separados para +0 y -0, por lo que el rango para una cantidad de 8 bits es de -127 a +127 .

En el complemento de 8 bits 2, los números de encoding -128 y +128 tienen la misma representación: 10000000 . Entonces, el diseñador del hardware se presenta con un dilema obvio: cómo interpretar el patrón de bits 10000000 . Formalmente, funcionará de cualquier manera. Si deciden interpretarlo como +128 , el rango resultante será -127..+128 . Si deciden interpretarlo como -128 , el rango resultante será -128..+127 .

En la representación del complemento real de 2 en la vida real, se elige este último enfoque porque satisface la siguiente convención: todos los patrones de bits con 1 en el bit de orden superior representan números negativos.

Sin embargo, vale la pena señalar que la especificación de lenguaje no requiere implementaciones de complemento a 2 para tratar el patrón de bits de 100...0 como un valor válido en cualquier tipo de entero con signo. Por ejemplo, las implementaciones pueden restringir caracteres de 8 bits con signed char a -127..+127 rango y considerar 10000000 como una combinación de bits no válida (representación de captura).

Creo que una manera fácil de explicar esto para el alma común es:

Un bit es un valor 0 o 1 , o 2 posibilidades

A 2 bits contiene dos combinaciones o 0 y 1 para cuatro valores posibles: 00 , 01 , 10 y 11 .

Un 3 bits contiene tres combinaciones para un total de ocho valores posibles: 000 a 111 .

Por lo tanto, n-bit contiene n combinaciones para un total de 2 ^ n valores posibles. Por lo tanto, un valor de 8 bits es 2 ^ 8 = 256 valores posibles.

Para los números firmados, el bit más significativo (el primero que lee el valor de izquierda a derecha) es el bit de signo; Eso deja una posibilidad de 2 ^ (n-1) valores posibles. Para un número con signo de 8 bits, esto es 2 ^ 7 = 128 valores posibles para cada signo. Pero como el signo positivo incluye el cero (0 a 127 = 128 valores diferentes, y 128 + 128 = 2 ^ 8 = 256), el signo negativo incluye -1 a … -128 para 128 valores diferentes también. Dónde :

 10000000 = -128 ... 11111111 = -1 00000000 = 0 ... 01111111 = 127 
 #include  #include  ... printf("range of signed character is %i ... %i", CHAR_MIN, CHAR_MAX ); 

Si solo considera dos complementos como módulo aritmético 256, entonces el corte entre positivo y negativo es puramente arbitrario. Podrías haberlo puesto en 63 / -192, 254 / -1, 130 / -125, o en cualquier otro lugar. Sin embargo, como un formato de entero con signo estándar, dos complementos llegaron por convención, puesto el límite en 127 / -128. Este corte tiene un gran beneficio: el bit alto que se establece corresponde directamente al número negativo.

En cuanto al lenguaje C, deja el formato de los números firmados hasta la implementación, pero solo ofrece 3 opciones de implementación, todas las cuales usan un “bit de signo”: signo / magnitud, complementos y dos complementos.

Si observas rangos de caracteres e inicios, parece que hay un número adicional en el lado negativo. Esto se debe a que un número negativo siempre se almacena como complemento de 2 de su binario. Por ejemplo, veamos cómo se almacena -128. En primer lugar, se calcula el binario de 128 (10000000), luego se obtiene su complemento de 1 (01111111). El complemento de 1 se obtiene cambiando todos los 0s a 1s y 1s a 0s. Finalmente, el complemento de 2 de este número, es decir, 10000000, se almacena. El complemento de 2 se obtiene sumndo 1 al complemento de 1. Así, para -128, se almacenan 10000000. Este es un número de 8 bits y se puede acomodar fácilmente en un char. A diferencia de esto, +128 no se puede almacenar en un char porque su binario 010000000 (el extremo izquierdo es para el signo positivo) es un número de 9 bits. Sin embargo, se puede almacenar +127 ya que su binario 01111111 resulta ser un número de 8 bits.