我正在参加 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。