我们可以假设 int 是 2 的补码的 32 位
唯一合法的运营商是: ! 〜& ^ | + >
此时我正在使用暴力
int a=0x01;
x=(x+1)>>1; //(have tried with just x instead of x+1 as well)
a = a+(!(!x));
...
最后 2 个陈述重复了 32 次。每次 x 移动一位时,a 就会加 1,并且对于所有 32 位,!= 0
使用测试编译器,它说我的方法在测试用例 0x7FFFFFFF(0 后跟 31 个 1)上失败,并说这个数字需要 32 位来表示。我不明白为什么这不是 31 (我的方法计算的)任何人都可以解释为什么吗?我需要改变什么来解决这个问题?
0x7FFFFFFF
确实需要 32 位。它可以表示为unsigned仅 31 位的整数:
111 1111 1111 1111 1111 1111 1111 1111
但如果我们使用二进制补码将其解释为有符号整数,那么前导1
则表明它是负数。所以我们必须前置一个前导0
:
0 111 1111 1111 1111 1111 1111 1111 1111
然后将其变为 32 位。
As for what you need to change — your current program actually has undefined behavior. If 0x7FFFFFFF
(231-1) is the maximum allowed integer value, then 0x7FFFFFFF + 1
cannot be computed. It is likely to result in -232, but there's absolutely no guarantee: the standard allow compilers to do absolutely anything in this case, and real-world compilers do in fact perform optimizations that can happen to give shocking results when you violate this requirement. Similarly, there's no specific guarantee what ... >> 1
will mean if ...
is negative, though in this case compilers are required, at least, to choose a specific behavior and document it. (Most compilers choose to produce another negative number by copying the leftmost 1
bit, but there's no guarantee of that.)
所以真正唯一确定的解决方法是:
- 使用不存在这些问题的算法重写整个代码;或者
- 专门检查以下情况
x
is 0x7FFFFFFF
(返回一个硬编码的32
)以及这种情况x
是负数(将其替换为~x
, i.e. -(x+1)
,并照常进行)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)