为什么我不能使用 int 的第一位?
Why can't I use the first bit of an int?
我正在尝试使用 int 的所有位生成一个随机数。当我使用 rand() 功能时,它似乎从来没有使用过第一位,所以我试图将整个事情转移到一个地方。但是,当我尝试打印新的移位数字时,它总是打印 4294967295,所以我猜这是一个溢出。但是,为什么我不能使用那个位?有办法吗?
如果不使用第一位,它可以正常工作,像这样(打印在随机数移位前后):
00000100001100111111001010010111
00001000011001111110010100101110
但如果需要第一位,则会发生这种情况:
01010110100001110011110011011111
42949672950101101000011100111100110111110
请帮忙!!它在技术上是可行的,它只是先打印数字...
typedef struct{
int blocks[NUM_BLOCKS];
} WWord;
void printbits(unsigned int n){
int i;
//printf("%u = ",n);
for(i=SIZE_OF_INT*SIZE_OF_BYTE-1;i>=0;i--){
int mask = 1<<i;
int maskedn = n&mask;
int thebit = maskedn >> i;
printf("%u",thebit);
}
printf("\n");
}
void fillword(WWord *word){
int i;
for(i=0; i<NUM_BLOCKS;i++){
unsigned int ran = rand();
printbits(ran);
ran = ran<<1;
printbits(ran);
word->blocks[i] = ran;
//word->blocks[i]<<1;
printf("\n");
}
}
您似乎在 printbits 函数中使用 int 而不是 unsigned int。所以它将它转换为 signed int ,它使用 MSB 作为符号位。将那些 int 更改为 unsigned int 它会起作用。
如下更改函数:
void printbits(unsigned int n){
int i;
//printf("%u = ",n);
for(i=SIZE_OF_INT*SIZE_OF_BYTE-1;i>=0;i--){
unsigned int mask = 1u<<i;
unsigned int maskedn = n&mask;
unsigned int thebit = maskedn >> i;
printf("%u",thebit);
}
printf("\n");
}
您的 maskedn
被声明为 int
类型。这是一个 有符号 数据类型。
但是你的 ran
是 unsigned
类型。
C 和 C++ 出于移位的目的对有符号和无符号整数类型进行不同的处理:>>
运算符对有符号整数的行为是根据 C 标准实现定义的,正如@chux 指出的那样在评论中。
然而,在大多数 x86 编译器上,有符号右移被实现为 arithmetic shift,这基本上意味着符号位(无符号表示中的最高有效位)被 保留 而不是向右移动。
如果您设置有符号整数的 MSB,那么您就是在设置 符号位 ,并且当您向右移动时,您正在复制该符号位并超过。参见
这就是为什么您得到一个非常大的数字 4294967295,即 (uint32_t)(0xFFFFFFFF)
,或 32 位 所有 设置为 1。
如果您在任何地方都小心使用无符号整数,那么您将获得预期的行为,即向右移动移动 MSB,而不是复制它。
我正在尝试使用 int 的所有位生成一个随机数。当我使用 rand() 功能时,它似乎从来没有使用过第一位,所以我试图将整个事情转移到一个地方。但是,当我尝试打印新的移位数字时,它总是打印 4294967295,所以我猜这是一个溢出。但是,为什么我不能使用那个位?有办法吗?
如果不使用第一位,它可以正常工作,像这样(打印在随机数移位前后):
00000100001100111111001010010111
00001000011001111110010100101110
但如果需要第一位,则会发生这种情况:
01010110100001110011110011011111
42949672950101101000011100111100110111110
请帮忙!!它在技术上是可行的,它只是先打印数字...
typedef struct{
int blocks[NUM_BLOCKS];
} WWord;
void printbits(unsigned int n){
int i;
//printf("%u = ",n);
for(i=SIZE_OF_INT*SIZE_OF_BYTE-1;i>=0;i--){
int mask = 1<<i;
int maskedn = n&mask;
int thebit = maskedn >> i;
printf("%u",thebit);
}
printf("\n");
}
void fillword(WWord *word){
int i;
for(i=0; i<NUM_BLOCKS;i++){
unsigned int ran = rand();
printbits(ran);
ran = ran<<1;
printbits(ran);
word->blocks[i] = ran;
//word->blocks[i]<<1;
printf("\n");
}
}
您似乎在 printbits 函数中使用 int 而不是 unsigned int。所以它将它转换为 signed int ,它使用 MSB 作为符号位。将那些 int 更改为 unsigned int 它会起作用。
如下更改函数:
void printbits(unsigned int n){
int i;
//printf("%u = ",n);
for(i=SIZE_OF_INT*SIZE_OF_BYTE-1;i>=0;i--){
unsigned int mask = 1u<<i;
unsigned int maskedn = n&mask;
unsigned int thebit = maskedn >> i;
printf("%u",thebit);
}
printf("\n");
}
您的 maskedn
被声明为 int
类型。这是一个 有符号 数据类型。
但是你的 ran
是 unsigned
类型。
C 和 C++ 出于移位的目的对有符号和无符号整数类型进行不同的处理:>>
运算符对有符号整数的行为是根据 C 标准实现定义的,正如@chux 指出的那样在评论中。
然而,在大多数 x86 编译器上,有符号右移被实现为 arithmetic shift,这基本上意味着符号位(无符号表示中的最高有效位)被 保留 而不是向右移动。
如果您设置有符号整数的 MSB,那么您就是在设置 符号位 ,并且当您向右移动时,您正在复制该符号位并超过。参见
这就是为什么您得到一个非常大的数字 4294967295,即 (uint32_t)(0xFFFFFFFF)
,或 32 位 所有 设置为 1。
如果您在任何地方都小心使用无符号整数,那么您将获得预期的行为,即向右移动移动 MSB,而不是复制它。