仅使用按位函数查找表示 2 的补码需要多少位
我们可以假设 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,并且 != 0 对于所有 32 位
使用测试编译器,它说我的方法在测试用例 0x7FFFFFFF(0 后跟 31 个 1)上失败,并说这个数字需要 32 位来表示。我不明白为什么这不是 31 (我的方法计算的)任何人都可以解释为什么吗?我需要改变什么来解决这个问题?
We can assume an int is 32 bits in 2's compliment
The only Legal operators are: ! ~ & ^ | + << >>
At this point i am using brute force
int a=0x01;
x=(x+1)>>1; //(have tried with just x instead of x+1 as well)
a = a+(!(!x));
...
with the last 2 statements repeated 32 times. This adds 1 to a everytime x is shifted one place and != 0 for all 32 bits
Using the test compiler it says my method fails on test case 0x7FFFFFFF (a 0 followed by 31 1's) and says this number requires 32 bits to represent. I dont see why this isnt 31 (which my method computes) Can anyone explain why? And what i need to change to account for this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
0x7FFFFFFF
确实需要 32 位。它可以表示为仅 31 位的无符号整数:但如果我们使用二进制补码将其解释为有符号整数,则前导
1
将表明它是负数。因此,我们必须在前面添加一个前导0
:,这样它就变成了 32 位。
至于你需要改变什么——你当前的程序实际上有未定义的行为。如果
0x7FFFFFFFF
(231-1) 是允许的最大整数值,则无法计算0x7FFFFFFF + 1
。它可能会导致 -232,但绝对不能保证:标准允许编译器在这种情况下执行任何操作,而现实世界的编译器实际上会执行可能会给出的优化当您违反此要求时,结果会令人震惊。同样,也没有具体保证...>> 1
表示如果...
为负数,但在这种情况下,编译器至少需要选择特定行为并记录它。 (大多数编译器选择通过复制最左边的1
位来生成另一个负数,但不能保证这一点。)因此,实际上唯一确定的修复方法是:
x
为0x7FFFFFFF
(返回硬编码的32
)的情况以及x
的情况为负(将其替换为~x
,即-(x+1)
,并照常进行)。0x7FFFFFFF
does require 32 bits. It could be expressed as an unsigned integer in only 31 bits:but if we interpret that as a signed integer using two's complement, then the leading
1
would indicate that it's negative. So we have to prepend a leading0
:which then makes it 32 bits.
As for what you need to change — your current program actually has undefined behavior. If
0x7FFFFFFF
(231-1) is the maximum allowed integer value, then0x7FFFFFFF + 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 leftmost1
bit, but there's no guarantee of that.)So really the only sure fix is either:
x
is0x7FFFFFFF
(returning a hardcoded32
) and the case thatx
is negative (replacing it with~x
, i.e.-(x+1)
, and proceeding as usual).请尝试此代码来检查有符号整数x是否可以装入n位。函数返回 1,否则返回 0。
Please try this code to check whether a signed integer x can be fitted into n bits. The function returns 1 when it does and 0 otherwise.