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

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

5 ответов


//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

этой хороший учебник для побитовых операций.

HTH.


вы можете сделать что-то вроде этого:

#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 или нет.

edit: найти MSB.

прежде всего прочитайте Endianess статьи, чтобы договориться о том, что MSB средства. В следующих строках мы предполагаем обращаться с big-endian нотация.

найти MSB, в следующем фрагменте мы сосредоточимся на применении правого сдвига до MSB будет ANDС 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 of a положительное целое число всегда 0, а MSB of a отрицательное целое число всегда 1.

вы можете проверить INT_MAX 32-битное представление:

INT_MAX: 01111111111111111111111111111111

сейчас. Почему цикл использует sizeof()? Если вы просто делаете цикл, как я написал в комментарии: (извините за = отсутствует в комментарии)

for (; a != 0; a >>= 1)
    MSB = a & 1;

вы получаете 1 всегда, потому что C++ не будет рассматривать "биты нулевой площадки" (потому что вы указали 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

int LSB = value & 1;
int MSB = value >> (sizeof(value)*8 - 1) & 1;

другие уже упоминалось:

int LSB = value & 1;

для получения наименее значительного бита. Но есть способ cheatier получить ГРЩ чем уже упоминалось. Если значение уже является подписанным типом, просто сделайте:

int MSB = value < 0;

если это неподписанное количество, приведите его к знаковому типу того же размера, например, если value был признан unsigned, do:

int MSB = (int)value < 0;

Да, официально, не портативный, неопределенное поведение, что угодно. Но на каждой второй системе дополнения и каждый компилятор для них, о котором я знаю, работает; в конце концов, высокий бит-это бит знака, поэтому, если подписанная форма отрицательна, то MSB-1, если она неотрицательна, MSB-0. Поэтому удобно, что подписанный тест для отрицательных чисел эквивалентен извлечению MSB.


LSB легко. Просто x & 1.

MSSB немного сложнее, так как байты не могут быть 8 битами, а sizeof(int) не может быть 4, и могут быть биты заполнения справа.

кроме того, с знаковое целое число, значит знаковый разряд МС значение бита.

Если вы имеете в виду знак бит, жизнь проста. Это просто x

Если вы имеете в виду самый значительный бит значения, чтобы быть полностью переносимым.

 int answer  = 0;
 int rack = 1;
 int mask  = 1;

 while(rack < INT_MAX)
 {
    rack << = 1;
    mask << = 1;
    rack |= 1; 
 } 

 return x & mask;

это многословный способ сделать это. На самом деле

x & (1