我需要检查 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 AND 其他任何位都是 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。
编辑:找到MSB。
首先阅读Endianess文章以就MSB
的含义达成一致。在下面的行中,我们假设使用大端表示法进行处理。为了找到
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
始终是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。
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
<< (sizeof(int) * CHAR_BIT) - 2); will be quite portable enough and your ints won't have padding bits.
int msb(int x){
if(x==0)return 0;
int iteration=16;
int bit_test=0x80008000;
while(((bit_test & x)==0)&(iteration!=0)){
x=x<<1;
iteration--;
}
iterator--;
if(x<0) return iteration+16;
return iteration;
}
您也可以调整它以使其成为 64 位,只需将 iteration=16
更改为
iteration=32
,然后将
iteration+16
更改为
iteration+32
,将
bit_test=80008000
更改为
bit_test=8000000080000000