【发布时间】:2013-04-25 22:28:42
【问题描述】:
我正在参加 Coursera 上的硬件/软件界面课程,我相信您已经从那里看到了其中的一些问题..
其中一项任务是确定 2 的补码整数 x 是否可以放入 n 位,仅使用运算符的子集等。我做得很好,但遇到了 2 种不同的方法,并用它们打了白板两者都充分了解它们。然后是混乱。
如果可以拟合,该函数返回 1,否则返回 0。
方法一(正确输出)
int fooBar(int x, int n) {
return !(((x << (32-n)) >> (32-n)) ^x);
}
以正整数执行
fooBar(5,3) == 0
正确计算出 5 不能表示为 2 的补码 3 位整数。
以负整数执行
fooBar(-4,3) == 1
正确计算出 -4 可以表示为 2 的补码 3 位整数。
方法一分析
x=5, n=3
00000000000000000000000000011101 32 - n == 29
10100000000000000000000000000000 x<<29
00000000000000000000000000000101 >> 29
00000000000000000000000000000101 5
XOR
00000000000000000000000000000101 5
--------------------------------
00000000000000000000000000000000 0
00000000000000000000000000000001 !0 == answer, 1.
如您所见,这将返回 0,如在 3 位内不能将 5 表示为 2 的补码整数。
方法二(输出错误)
int fooBar(int x, int n) {
return !((x & ~(1 << (32-n))) ^x);
}
以正整数执行
fooBar(5,3) == 1
误报。
以负整数执行
fooBar(-4,3) == 0
假阴性。
方法二分析
x=5, n=3
00000000000000000000000000011101 32 - n == 29
11011111111111111111111111111111 ~(1<<29)
AND
00000000000000000000000000000101 5
--------------------------------
00000000000000000000000000000101 5
00000000000000000000000000000101 5
XOR
00000000000000000000000000000101 5
--------------------------------
00000000000000000000000000000000 0
00000000000000000000000000000001 !0 == answer, 1.
我正在编译:
gcc version 4.7.2 (Debian 4.7.2-5)
问题
当分析表明在位级别上一切都相同时,我无法解释输出的差异,所以任何关于我可以在哪里为自己阐明这一点的提示/提示都非常重要赞赏。
感谢您的宝贵时间!
sc.
【问题讨论】:
标签: c bit-manipulation