mascara computing c++ c bit-manipulation masking bit-masks

c++ - computing - ¿Cuál es el propósito de "int mask=~ 0;"?



mascara de bits (6)

C y C ++ permiten 3 formatos de entero con signo diferentes: signo-magnitud, complemento de uno y complemento de dos

~0 producirá todos los bits, independientemente del formato de signo que utilice el sistema. Entonces es más portátil que -1

Puede agregar el sufijo U (es decir, -1U ) para generar un patrón de bits de uno a uno de forma portátil 1 . Sin embargo ~0 indica la intención más clara : invierta todos los bits en el valor 0, mientras que -1 mostrará que se necesita un valor de menos uno, no su representación binaria

1 porque las operaciones sin signo siempre se reducen en módulo el número que es uno mayor que el valor más grande que puede representarse por el tipo resultante

Vi la siguiente línea de código here en C.

int mask = ~0;

Imprimí el valor de la mask en C y C ++. Siempre imprime -1 .

Entonces tengo algunas preguntas:

  • ¿Por qué asignar valor ~0 a la variable de máscara ?
  • ¿Cuál es el propósito de ~0 ?
  • ¿Podemos usar -1 lugar de ~0 ?

Es una forma portátil de establecer todos los bits binarios en un entero de 1 bit sin tener que saber cuántos bits hay en el entero en la arquitectura actual.


Está estudiando un desafío de codificación con una serie de restricciones sobre operadores y construcciones de lenguaje para realizar determinadas tareas.

El primer problema es devolver el valor -1 sin el uso del operador - .

En máquinas que representan números negativos con el complemento de dos, el valor -1 se representa con todos los bits establecidos en 1 , por lo que ~0 evalúa a -1 :

/* * minusOne - return a value of -1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 2 * Rating: 1 */ int minusOne(void) { // ~0 = 111...111 = -1 return ~0; }

Otros problemas en el archivo no siempre se implementan correctamente. El segundo problema, devolver un valor booleano que representa el hecho de que un valor int encajaría en un short firmado de 16 bits tiene un defecto:

/* * fitsShort - return 1 if x can be represented as a * 16-bit, two''s complement integer. * Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 8 * Rating: 1 */ int fitsShort(int x) { /* * after left shift 16 and right shift 16, the left 16 of x is 00000..00 or 111...1111 * so after shift, if x remains the same, then it means that x can be represent as 16-bit */ return !(((x << 16) >> 16) ^ x); }

Cambiando a la izquierda un valor negativo o un número cuyo valor desplazado está más allá del rango de int tiene un comportamiento indefinido, el desplazamiento a la derecha de un valor negativo se define como implementación, por lo que la solución anterior es incorrecta (aunque probablemente sea la solución esperada).


Existen múltiples formas de codificar números en todas las arquitecturas de computadora. Al usar el complemento de 2, esto siempre será cierto: ~0 == -1 . Por otro lado, algunas computadoras usan el complemento de 1 para codificar números negativos para los cuales el ejemplo anterior no es cierto, porque ~0 == -0 . Sí, el complemento 1 tiene cero negativo, y es por eso que no es muy intuitivo.

Entonces a tus preguntas

  • el ~ 0 se asigna a la máscara para que todos los bits en la máscara sean iguales 1 -> haciendo mask & sth == sth
  • el ~ 0 se usa para hacer que todos los bits sean iguales a 1 independientemente de la plataforma utilizada
  • puede usar -1 en lugar de ~ 0 si está seguro de que la plataforma de su computadora utiliza la codificación del número de complemento de 2

Mi pensamiento personal: haga que su código sea tan independiente de la plataforma como sea posible. El costo es relativamente pequeño y el código se vuelve a prueba de fallas


Hace mucho tiempo, así era como se guardaba la memoria en equipos extremadamente limitados, como la computadora 1K ZX 80 o ZX 81. En BASIC, lo harías

Let X = NOT PI

más bien que

LET X = 0

Dado que los números se almacenaron como puntos flotantes de 4 bytes, este último toma 2 bytes más que la primera alternativa NOT PI, donde cada uno de NOT y PI ocupa un solo byte.


Que en una plataforma de complemento a 2 (que se asume) te da -1, pero la escritura -1 directamente está prohibida por las reglas (solo números enteros 0..255, unario ! ~ Y binario & , ^ , | , + , << y >> están permitidos).