Подтвердить что ты не робот

Проверьте значение младшего значащего бита (LSB) и самого значимого бита (MSB) в C/С++

Мне нужно проверить значение младшего значащего бита (LSB) и самого значимого бита (MSB) целого числа в C/С++. Как мне это сделать?

4b9b3361

Ответ 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 не будут иметь биты дополнений.