我的代码的目的是在我的int(32位)表示的右边创建一个n个零的掩码。我的方法是首先将负数存储在变量中,然后将其向左移动n个空格以向右移动n个零。代码如下:
int mask(int n){
int neg1=(1<<31)>>31;
int mask=neg1<<n;
return mask;
}
尽管如此,当n为32时,我想获得值0x0,但我得到的是0xffffffff(neg1)。当我转换到变量时会发生这种情况。但是当我转向恒定本身时,它就像一个魅力。新代码将是:
mask=0xffffffff<<n;
尽管如此,我不允许使用超过8位的常量。所以我需要存储在另一个变量中的值。有人可以告诉我为什么会这样,我该如何解决?
非常感谢你!
答案 0 :(得分:1)
当尝试向左移动到32位int
的符号位时,OP的代码调用未定义的行为。
E1的结果&lt;&lt; E2是E1左移E2位位置;腾出的位用零填充。 ...如果E1具有有符号类型和非负值,并且E1×2E2在结果类型中可表示,那么这就是结果值;否则,行为未定义。 C11§6.5.74
而是使用无符号类型来避免移位为31的错误定义的行为.32位unsigned
上的32+移位也是一个问题。
一种简单的方法使用更广泛的类型。
#include <stdio.h>
#include <inttypes.h>
uint32_t mask32(int n) {
return 0 - (1ull << n);
}
int main(void) {
for (int i=0; i<=32; i++) {
printf("%2d %lX\n", i, (unsigned long) mask32(i));
}
}
输出
0 FFFFFFFF
1 FFFFFFFE
2 FFFFFFFC
...
29 E0000000
30 C0000000
31 80000000
32 0