我正在编写一个C函数,该函数接受参数n并返回一个整数,该整数以n的位表示形式表示,其后是足够的0以填充数据类型(总共32位)。我的代码当前如下所示:
int upperBits(int n) {
int retval = 0 - 1;
int shift = 32 - n;
retval = retval << shift;
return retval;
}
当n = 0时,此代码失败,返回值-1由32 1而不是0表示。但是,当我用文字替换shift时:
int upperBits(int n) {
int retval = 0 - 1;
int shift = 32 - n;
retval = retval << 32;
return retval;
}
代码正常工作,返回0。当使用n = 0调用函数时,我使用了print语句来验证shift = 32,所以我不明白为什么它们的行为不同。是什么导致了这种差异,我该如何规避呢?
如果相关,则代码在Linux机器上运行,并使用gcc进行编译。我只需要对这些运算符使用直线代码:
!
˜
&
ˆ
|
+
<<
>>
编辑:
我仍然不知道到底是什么问题,还是一个好的解决方案,但是这种解决方法很有效:
int upperBits(int n) {
int retval = 0 - 1;
int shift = 32 - n;
int isnull = !(n);
printf ("%x %x %x \n", retval, shift, n);
retval = retval << (shift - isnull);
retval = retval << isnull;
printf ("%x %x %x \n", retval, shift, n);
return retval;
}
最佳答案
您正在执行非法的左移。
向左移动负数会调用undefined behavior,向左移动大于或等于所讨论类型的位宽的数量也是如此。
C standard的6.5.7节中有关按位移位运算符的规定:
您可以通过使用无符号类型并检查移位的大小来纠正此问题:
uint32_t upperBits(int n) {
uint32_t retval = 0xffffffff;
if (n <= 0 || n > 32) {
return 0;
} else {
int shift = 32 - n;
retval = retval << shift;
return retval;
}
}
关于c - 文字常量和具有相同值的变量之间左移执行的差异,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52650933/