Мне нужно проверить значение младшего значащего бита (LSB) и самого значимого бита (MSB) целого числа в C/С++. Как мне это сделать?
Проверьте значение младшего значащего бита (LSB) и самого значимого бита (MSB) в C/С++
Ответ 1
//int value;
int LSB = value & 1;
Альтернативно (что теоретически не переносимо, но практически оно есть - см. комментарий Стива)
//int value;
int LSB = value % 2;
Детали: Вторая формула проще. Оператор% - оператор остатка. Число LSB равно 1, если это нечетное число и 0 в противном случае. Итак, мы проверяем остаток деления на 2. Логика первой формулы такова: номер 1 в двоичном выражении таков:
0000...0001
Если вы двоичный - и это с произвольным числом, все биты результата будут равны 0, кроме последнего, потому что 0 И все остальное равно 0. Последний бит результата будет равен 1, если последний бит вашего число равно 1, потому что 1 & 1 == 1
и 1 & 0 == 0
Это - хороший учебник для побитовых операций.
НТН.
Ответ 2
Вы можете сделать что-то вроде этого:
#include <iostream>
int main(int argc, char **argv)
{
int a = 3;
std::cout << (a & 1) << std::endl;
return 0;
}
Таким образом, вы AND
свою переменную с LSB, потому что
3: 011
1: 001
в 3-битном представлении. Итак, AND
:
AND
-----
0 0 | 0
0 1 | 0
1 0 | 0
1 1 | 1
Вы узнаете, есть ли LSB 1 или нет.
изменить: найти MSB.
Прежде всего прочтите статью Endianess, чтобы договориться о том, что означает MSB
. В следующих строках мы предположим, что будем обрабатывать с большими обозначениями.
Чтобы найти MSB
, в следующем фрагменте мы будем фокусировать применение правого сдвига до тех пор, пока MSB
не будет AND
ed с 1
.
Рассмотрим следующий код:
#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;
}
Если вы печатаете MSB
вне цикла, вы получите 0
.
Если вы измените значение a
:
unsigned int a = UINT_MAX; // found in <limits.h>
MSB
будет 1
, потому что его 32-битное представление:
UINT_MAX: 11111111111111111111111111111111
Однако, если вы сделаете то же самое с подписанным целым числом, все будет по-другому.
#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;
}
Как я уже сказал в комментарии ниже, MSB
положительное целое число всегда 0
, а MSB
отрицательного целого всегда 1
.
Вы можете проверить 32-битное представление INT_MAX:
INT_MAX: 01111111111111111111111111111111
Теперь. Почему цикл использует sizeof()
?
Если вы просто выполняете цикл, как я писал в комментарии: (извините за =
отсутствует в комментарии)
for (; a != 0; a >>= 1)
MSB = a & 1;
вы всегда будете получать 1
, потому что С++ не будет рассматривать "бит с нулевой точкой" (поскольку вы указали a != 0
в качестве оператора выхода) выше самого высокого 1
. Например, для 32-битных целых чисел:
int 7 : 00000000000000000000000000000111
^ this will be your fake MSB
without considering the full size
of the variable.
int 16: 00000000000000000000000000010000
^ fake MSB
Ответ 3
int LSB = value & 1;
int MSB = value >> (sizeof(value)*8 - 1) & 1;
Ответ 4
Другие уже упомянули:
int LSB = value & 1;
для получения младшего значащего бита. Но есть шикарный способ получить MSB, чем было упомянуто. Если значение уже зарегистрировано, просто выполните:
int MSB = value < 0;
Если это количество без знака, переведите его в подписанный тип того же размера, например. если value
был объявлен как unsigned
, do:
int MSB = (int)value < 0;
Да, официально, не переносимо, undefined поведение, что угодно. Но на каждой из двух систем дополнения и каждого компилятора для них, о которых я знаю, это работает; в конце концов, старший бит является битом знака, поэтому, если подписанная форма отрицательна, то MSB равен 1, если он неотрицателен, MSB равен 0. Поэтому удобно, что подписанный тест для отрицательных чисел эквивалентен извлечению MSB.
Ответ 5
LSB легко. Просто x и 1.
MSSB немного сложнее, так как байты не могут быть 8 бит, а sizeof (int) может быть не 4, и могут быть биты дополнения справа.
Кроме того, со знаком целого числа, вы имеете в виду знаковый бит бит значения MS.
Если вы имеете в виду знаковый бит, жизнь проста. Это просто x < 0
Если вы имеете в виду самый значительный бит значения, он будет полностью переносимым.
int answer = 0;
int rack = 1;
int mask = 1;
while(rack < INT_MAX)
{
rack << = 1;
mask << = 1;
rack |= 1;
}
return x & mask;
Это длинный способ сделать это. В действительности
x и (1 < (sizeof (int) * CHAR_BIT) - 2); будет достаточно переносимым, и ваши ints не будут иметь биты дополнений.