tabla - Compruebe el valor del bit menos significativo(LSB) y el bit más significativo(MSB) en C/C++
sistema binario informatica pdf (5)
LSB es fácil. Sólo x y 1.
MSSB es un poco más complicado, ya que los bytes no pueden ser de 8 bits y el tamaño de (int) no puede ser de 4, y puede haber bits de relleno a la derecha.
Además, con un entero con signo, ¿se refiere al bit de signo del bit de valor de MS?
Si te refieres al bit de signo, la vida es fácil. Es solo x <0
Si te refieres al bit de valor más significativo, ser completamente portátil.
int answer = 0;
int rack = 1;
int mask = 1;
while(rack < INT_MAX)
{
rack << = 1;
mask << = 1;
rack |= 1;
}
return x & mask;
Esa es una manera larga de hacerlo. En realidad
x & (1 << (sizeof (int) * CHAR_BIT) - 2); será lo suficientemente portátil y sus entradas no tendrán partes de relleno.
Necesito verificar el valor del bit menos significativo (LSB) y el bit más significativo (MSB) de un entero en C / C ++. ¿Cómo haría esto?
Otros ya han mencionado:
int LSB = value & 1;
para obtener el bit menos significativo. Pero hay una manera más engañosa de obtener el MSB de lo que se ha mencionado. Si el valor ya es un tipo firmado, simplemente haga:
int MSB = value < 0;
Si es una cantidad sin firmar, cámbiela al tipo firmado del mismo tamaño; por ejemplo, si el value
se declaró unsigned
, haga lo siguiente:
int MSB = (int)value < 0;
Sí, oficialmente, no portable, comportamiento indefinido, lo que sea. Pero en el sistema de complemento de cada dos y en cada compilador de los que tengo conocimiento, sucede que funciona; después de todo, el bit alto es el bit de signo, por lo que si el formulario firmado es negativo, entonces el MSB es 1, si no es negativo, el MSB es 0. Entonces, convenientemente, una prueba firmada para números negativos equivale a recuperar el MSB.
Puedes hacer algo como esto:
#include <iostream>
int main(int argc, char **argv)
{
int a = 3;
std::cout << (a & 1) << std::endl;
return 0;
}
De esta manera usted AND
su variable con el LSB, porque
3: 011
1: 001
En representación de 3 bits. Así que siendo AND
:
AND
-----
0 0 | 0
0 1 | 0
1 0 | 0
1 1 | 1
Podrás saber si LSB es 1 o no.
Editar: encontrar MSB.
En primer lugar, lea el artículo de Endianess para acordar qué significa MSB
. En las siguientes líneas suponemos que manejamos con notación big-endian.
Para encontrar el MSB
, en el siguiente fragmento nos enfocaremos aplicando un cambio a la derecha hasta que el MSB
sea AND
editado con 1
. Considere el siguiente código:
#include <iostream>
#include <limits.h>
int main(int argc, char **argv)
{
unsigned int a = 128; // we want to find MSB of this 32-bit unsigned int
int MSB = 0; // this variable will represent the MSB we''re looking for
// sizeof(unsigned int) = 4 (in Bytes)
// 1 Byte = 8 bits
// So 4 Bytes are 4 * 8 = 32 bits
// We have to perform a right shift 32 times to have the
// MSB in the LSB position.
for (int i = sizeof(unsigned int) * 8; i > 0; i--) {
MSB = (a & 1); // in the last iteration this contains the MSB value
a >>= 1; // perform the 1-bit right shift
}
// this prints out ''0'', because the 32-bit representation of
// unsigned int 128 is:
// 00000000000000000000000010000000
std::cout << "MSB: " << MSB << std::endl;
return 0;
}
Si imprime MSB
fuera del ciclo, obtendrá 0
. Si cambia el valor de a
:
unsigned int a = UINT_MAX; // found in <limits.h>
MSB
será 1
, porque su representación de 32 bits es:
UINT_MAX: 11111111111111111111111111111111
Sin embargo, si haces lo mismo con un entero con signo, las cosas serán diferentes.
#include <iostream>
#include <limits.h>
int main(int argc, char **argv)
{
int a = -128; // we want to find MSB of this 32-bit unsigned int
int MSB = 0; // this variable will represent the MSB we''re looking for
// sizeof(int) = 4 (in Bytes)
// 1 Byte = 8 bits
// So 4 Bytes are 4 * 8 = 32 bits
// We have to perform a right shift 32 times to have the
// MSB in the LSB position.
for (int i = sizeof(int) * 8; i > 0; i--) {
MSB = (a & 1); // in the last iteration this contains the MSB value
a >>= 1; // perform the 1-bit right shift
}
// this prints out ''1'', because the 32-bit representation of
// int -128 is:
// 10000000000000000000000010000000
std::cout << "MSB: " << MSB << std::endl;
return 0;
}
Como dije en el comentario a continuación, el MSB
de un entero positivo siempre es 0
, mientras que el MSB
de un entero negativo siempre es 1
.
Puedes verificar la representación de 32 bits de INT_MAX:
INT_MAX: 01111111111111111111111111111111
Ahora. ¿Por qué el ciclo usa sizeof()
? Si simplemente haces el ciclo como escribí en el comentario: (perdón por =
falta en el comentario)
for (; a != 0; a >>= 1)
MSB = a & 1;
obtendrá 1
siempre, porque C ++ no considerará los ''bits de cero-pad'' (porque especificó a != 0
como declaración de salida) más alto que el 1
más alto. Por ejemplo, para enteros de 32 bits tenemos:
int 7 : 00000000000000000000000000000111
^ this will be your fake MSB
without considering the full size
of the variable.
int 16: 00000000000000000000000000010000
^ fake MSB
//int value;
int LSB = value & 1;
Alternativamente (lo que no es teóricamente portátil, pero prácticamente lo es - vea el comentario de Steve)
//int value;
int LSB = value % 2;
Detalles: La segunda fórmula es más sencilla. El operador% es el operador de resto. El LSB de un número es 1 si es un número impar y 0 en caso contrario. Entonces verificamos el resto de dividir con 2. La lógica de la primera fórmula es esta: el número 1 en binario es este:
0000...0001
Si tiene un binario Y esto con un número arbitrario, todos los bits del resultado serán 0 excepto el último porque 0 Y cualquier otra cosa es 0. El último bit del resultado será 1 si el último bit de su número fue 1 porque 1 & 1 == 1
y 1 & 0 == 0
This es un buen tutorial para operaciones bitwise.
HTH.
int LSB = value & 1;
int MSB = value >> (sizeof(value)*8 - 1) & 1;