C/ c++中最低有效位(LSB)和最高有效位(MSB)的校验值

Check value of least significant bit (LSB) and most significant bit (MSB) in C/C++

本文关键字:有效位 MSB 校验 c++ LSB      更新时间:2023-10-16

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

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

或者(理论上是不可移植的,但实际上是可移植的——参见Steve的评论)

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

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

0000...0001

如果你对一个任意的数字进行二进制与运算,结果的所有位都将是0,除了最后一位,因为0和其他任何位都是0。如果您的数字的最后一位是1,则结果的最后一位将是1,因为1 & 1 == 11 & 0 == 0

这是一个很好的位操作教程。

HTH .

你可以这样做:

#include <iostream>
int main(int argc, char **argv)
{
    int a = 3;
    std::cout << (a & 1) << std::endl;
    return 0;
}

这样你用LSB来AND你的变量,因为

3: 011
1: 001

用3位表示。所以是AND:

AND
-----
0  0  | 0
0  1  | 0
1  0  | 0
1  1  | 1

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

edit: find MSB.

首先,阅读Endianess文章,同意MSB的含义。在接下来的几行中,我们将使用大端表示法。

为了找到MSB,在下面的代码片段中,我们将重点应用右移,直到MSB1成为AND。考虑下面的代码:

#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
int LSB = value & 1;
int MSB = value >> (sizeof(value)*8 - 1) & 1;

别人已经提到过:

int LSB = value & 1;

表示获取最低有效位。但是,要获得MSB,还有一种比上面提到的更不诚实的方法。如果值已经是有符号类型,只需执行:

int MSB = value < 0;

如果它是一个无符号量,将其强制转换为相同大小的有符号类型,例如,如果value被声明为unsigned,则执行:

int MSB = (int)value < 0;

是的,正式的,不可移植的,未定义的行为,等等。但在我所知道的每一个二补系统和每一个编译器上,它都是有效的;毕竟,高位是符号位,所以如果有符号的形式是负的,那么MSB是1,如果它是非负的,MSB是0。因此,对负数进行有符号检验就相当于检索MSB。

LSB很容易。只是x &1 .

MSSB有点棘手,因为bytes可能不是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) & lt; & lt;(sizeof(int) * CHAR_BIT) - 2);将具有足够的可移植性,并且你的int值不会有填充位