检查C/C++中的最低有效位(LSB)和最高有效位(MSB)的值

del*_*992 21 c c++ integer bit-manipulation bit

我需要检查C/C++中整数的最低有效位(LSB)和最高有效位(MSB)的值.我该怎么做?

Arm*_*yan 21

//int value;
int LSB = value & 1;
Run Code Online (Sandbox Code Playgroud)

或者(理论上不是便携式的,但实际上是 - 见史蒂夫的评论)

//int value;
int LSB = value % 2;
Run Code Online (Sandbox Code Playgroud)

细节: 第二个公式更简单.%运算符是余数运算符.如果数字为奇数,则数字的LSB为1,否则为0.所以我们检查除以2的余数.第一个公式的逻辑是这样的:二进制数字1是这样的:

0000...0001
Run Code Online (Sandbox Code Playgroud)

如果你使用任意数字二进制和AND,结果的所有位都将为0,除了最后一位,因为0和其他任何东西都是0.如果你的数字的最后一位是1,结果的最后一位将是1因为1 & 1 == 1和1 & 0 == 0

这是按位操作的好教程.

HTH.

  • IMO"%2"是愚蠢的,因为虽然它在实践中起作用,但这只是因为在实践中所有C++实现都使用二进制补码表示负整数.从理论上讲,它不一定有效,因为理论上"-1"可能使其LSB清晰(单个补码).如果测试是针对*最后一位*,则使用*bitwise*运算符,而不是模数运算符,它与位有任何内在关系:-) (10认同)
  • 实际上,模运算符无法获取 _all_ 架构上的 LSB 值,因为向零舍入,对于奇数负值,它返回 -1 而不是 +1。从技术上讲,在 C99 之前,允许向负无穷大舍入,从而产生正确的值,但我在野外只遇到过一种这样的架构。 (2认同)

dav*_*ave 13

你可以这样做:

#include <iostream>

int main(int argc, char **argv)
{
    int a = 3;
    std::cout << (a & 1) << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这样你就AND可以使用LSB变量,因为

3: 011
1: 001
Run Code Online (Sandbox Code Playgroud)

以3位表示.所以AND:

AND
-----
0  0  | 0
0  1  | 0
1  0  | 0
1  1  | 1
Run Code Online (Sandbox Code Playgroud)

您将能够知道LSB是否为1.

编辑:找到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;
}
Run Code Online (Sandbox Code Playgroud)

如果您MSB在周期外打印,您将获得0.如果更改以下值a:

unsigned int a = UINT_MAX; // found in <limits.h>
Run Code Online (Sandbox Code Playgroud)

MSB将是1,因为它的32位表示是:

UINT_MAX: 11111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)

但是,如果你使用有符号整数做同样的事情,事情会有所不同.

#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;
}
Run Code Online (Sandbox Code Playgroud)

正如我在下面的评论说,在MSB一个的正整数始终0,而MSB一个的负整数始终1.

您可以检查INT_MAX 32位表示:

INT_MAX: 01111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)

现在.为什么循环使用sizeof()?如果您只是按照我在评论中写的那样进行循环:(对于=评论中遗漏而感到抱歉)

for (; a != 0; a >>= 1)
    MSB = a & 1;
Run Code Online (Sandbox Code Playgroud)

你将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
Run Code Online (Sandbox Code Playgroud)


Zde*_*las 6

int LSB = value & 1;
int MSB = value >> (sizeof(value)*8 - 1) & 1;
Run Code Online (Sandbox Code Playgroud)