C. x的最低有效字节中的位都等于1
D. x的最高有效字节中的位都等于0
代码应该遵循位级整数编码规则,另外还有一个限制,不能使用(==)和(!=)测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
/*
* 2.61.c
*/
#include <stdio.h>
#include <assert.h>
int A(int x) {
return !~x;
}
int B(int x) {
return !x;
}
int C(int x) {
return A(x | ~0xff);
}
int D(int x) {
return B((x >> ((sizeof(int)-1) << 3)) & 0xff);
}
int main(int argc, char* argv[]) {
int all_bit_one = ~0;
int all_bit_zero = 0;
assert(A(all_bit_one));
assert(!B(all_bit_one));
assert(C(all_bit_one));
assert(!D(all_bit_one));
assert(!A(all_bit_zero));
assert(B(all_bit_zero));
assert(!C(all_bit_zero));
assert(D(all_bit_zero));
// test magic number 0x1234ff
assert(!A(0x1234ff));
assert(!B(0x1234ff));
assert(C(0x1234ff));
assert(D(0x1234ff));
// test magic number 0x1234
assert(!A(0x1234));
assert(!B(0x1234));
assert(!C(0x1234));
assert(D(0x1234));
return 0;
}
|
2.62编写一个函数int_shifts_are_arithemtic(),在对int类型的数使用算数右移的机器上运行时这个函数生成1,而其他情况下生成0.你的代码应该可以运行在任何字长的机器上。在几种机器上测试你的代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/*
* int-shifts-are-arithemetic.c
*/
#include <stdio.h>
#include <assert.h>
int int_shifts_are_arithemetic() {
int num = -1;
return !(num ^ (num >> 1));
}
int main(int argc, char* argv[]) {
assert(int_shifts_are_arithemetic());
return 0;
}
|
2.63 将下面的c代码补充完整。函数srl用算术右移(由值xsra给出)来完成逻辑右移,后面的其他操作不包括右移或者除法。函数sra用逻辑右移(由值xsrl给出)来完成算术右移,后面的其他操作不包括右移或者除法。可以通过计算8*sizeof(int)来确定数据类型int中的位数w。位移量k的取值范围为0~w-1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
/*
* srl-sra.c
*/
#include <stdio.h>
#include <assert.h>
unsigned srl(unsigned x, int k) {
unsigned xsra = (int) x >> k;
int w = sizeof(int) << 3;
int mask = (int) -1 << (w - k);
return xsra & ~mask;
}
int sra(int x, int k) {
int xsrl = (unsigned) x >> k;
int w = sizeof(int) << 3;
int mask = (int) -1 << (w - k);
//let mask remain unchanged when the first bit of x is 1, otherwise 0.
int m = 1 << (w - 1);
mask &= ! (x & m) - 1;
return xsrl | mask;
}
int main(int argc, char* argv[]) {
unsigned test_unsigned = 0x12345678;
int test_int = 0x12345678;
assert(srl(test_unsigned, 4) == test_unsigned >> 4);
assert(sra(test_int, 4) == test_int >> 4);
test_unsigned = 0x87654321;
test_int = 0x87654321;
assert (srl (test_unsigned, 4) == test_unsigned >> 4);
assert (sra (test_int, 4) == test_int >> 4);
return 0;
}
|
2.64 写出代码实现如下函数:
1
2
|
/*Return 1 when any odd bit of x equals 1; 0 otherwise. Assume w=32 */
int any_odd_one(unsigned x)
|
函数应该遵循位级整数编码规则,不过你可以假设数据类型int有w=32位。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/*
* any-odd-one.c
*/
#include <stdio.h>
#include <assert.h>
int any_odd_one(unsigned x) {
return !!(0xAAAAAAAA & x);
}
int main(int argc, char* argv[]) {
assert(any_odd_one(0x2));
assert(!any_odd_one(0x4));
return 0;
}
|
2.65 写出代码实现如下函数:
1
2
|
/* return 1 when x contains an odd number of 1s; 0 otherwise. Assume w =32 */
int odd_ones(unsigned x);
|
函数应该遵循位级整数编码规则,不过你可以假设数据类型int有w=32位。你的代码最多只能包含12个算数运算,位运算和逻辑运算。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/*
* odd-ones.c
*/
#include <stdio.h>
#include <assert.h>
int odd_ones(unsigned x) {
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
x &= 0x1;
return x;
}
int main(int argc, char* argv[]) {
assert(odd_ones(0x10101011));
assert(!odd_ones(0x01010101));
return 0;
}
|
代码参考自GitHub