我们可以假设int是32位的2位赞美 唯一的法律运营商是:! 〜& ^ | +<< >>
此时我正在使用蛮力
int a=0x01;
x=(x+1)>>1; //(have tried with just x instead of x+1 as well)
a = a+(!(!x));
... 最后2个语句重复32次。每增加1次,x移位一位,而!= 0,所有32位
使用测试编译器,它说我的方法在测试用例0x7FFFFFFF(0后跟31 1)上失败,并说这个数字需要32位来表示。我不明白为什么这不是31(我的方法计算)谁能解释为什么?我需要改变什么才能解释这个问题?
答案 0 :(得分:2)
0x7FFFFFFF
确实需要32位。它可以表示为仅仅31位的无符号整数:
111 1111 1111 1111 1111 1111 1111 1111
但如果我们将其解释为使用两个补码的有符号整数,那么前导1
将表明它是否定的。所以我们必须在前导0
前加上
0 111 1111 1111 1111 1111 1111 1111 1111
然后使其成为32位。
至于你需要改变什么 - 你当前的程序实际上有未定义的行为。如果0x7FFFFFFF
(2 31 -1)是允许的最大整数值,则无法计算0x7FFFFFFF + 1
。它可能导致-2 32 ,但绝对不能保证:标准允许编译器在这种情况下完全做任何事情,而实际编译器实际上执行优化当你违反这个要求时,可能会发生令人震惊的结果。同样,如果... >> 1
为负数,则没有具体保证...
意味着什么,但在这种情况下,编译器至少需要选择特定行为并记录它。 (大多数编译器选择通过复制最左边的1
位来产生另一个负数,但是不能保证这一点。)
所以唯一可靠的解决办法是:
x
是0x7FFFFFFF
(返回硬编码32
)的情况以及x
为否定的情况(将其替换为{{1} },即~x
,并照常进行。答案 1 :(得分:2)
请尝试使用此代码检查有符号整数 x 是否可以装入 n 位。函数返回1,否则返回0。
// http://www.cs.northwestern.edu/~wms128/bits.c
int check_bits_fit_in_2s_complement(signed int x, unsigned int n) {
int mask = x >> 31;
return !(((~x & mask) + (x & ~mask))>> (n + ~0));
}