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

时间:2011-07-11 08:52:55

标签: c++ c integer bit-manipulation bit

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

5 个答案:

答案 0 :(得分:21)

//int value;
int LSB = value & 1;

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

//int value;
int LSB = value % 2;

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

0000...0001

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

This是按位操作的好教程。

HTH。

答案 1 :(得分:13)

您可以这样做:

#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的含义达成一致意见。在以下几行中,我们假设使用big-endian表示法处理。

要查找MSB,我们将在以下代码段中重点应用右移,直到MSBAND进行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

您可以检查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

答案 2 :(得分:6)

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

答案 3 :(得分:2)

其他人已经提到:

int LSB = value & 1;

获得最低位。但是,有一种更加愚蠢的方式来获得MSB。如果值已经是签名类型,只需执行:

int MSB = value < 0;

如果它是未签名的数量,请将其投放到相同尺寸的签名类型,例如如果value被声明为unsigned,请执行:

int MSB = (int)value < 0;

是的,正式的,不可移植的,未定义的行为,等等。但是在我所知道的每两个补充系统和它们的每个编译器上,它恰好起作用;毕竟,高位是符号位,所以如果有符号形式为负,则MSB为1,如果它是非负的,则MSB为0.所以方便的是,负数的签名测试是相当于检索MSB。

答案 4 :(得分:0)

LSB很简单。只是x&amp; 1。

MSSB有点棘手,因为字节可能不是8位而sizeof(int)可能不是4,并且可能在右边有填充位。

另外,对于有符号整数,是指MS值位的符号位。

如果你的意思是标志位,生活很容易。只是x&lt; 0

如果你的意思是最重要的一点,那就是完全可移植。

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

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

 return x & mask;

这是一种冗长的做法。实际上

x&amp; (1&lt;&lt;(sizeof(int)* CHAR_BIT) - 2); 将足够便携,你的整体不会有填充位。