2.42 编写一个c表达式,生成一个字,由x的最低有效字节和y中剩下的字节组成。对于对于运算数 x = 0x89ABCDEF 和 y = 0x76543210,生成的结果是0x765432EF函数
答:分析一下,测试
a>. 这道题目主要考的是我们逻辑运算的使用,首先我们来回顾一下都有哪些逻辑运算:spa
按位与(&):(双目运算)相同位均为1,结果为1,不然结果为0code
按位或(|):(双目运算)相同位有一个是1的结果为1,不然结果为0blog
按位异或(^):(双目运算)相同位值相同的结果为0,不然为1it
按位取反(~):这是单目运算,有效位值是1的,结果为0,值为0的结果为1io
还有其余的几个运算:什么同一运算、位移运算(左移位运算<<;右移位运算>> 又分为正数和负数,正数跟左移位运算同样,负数就分为逻辑运算补0,算术运算补1的区别)class
b>. 从结果来看0x765432EF的前三位是y的前三位0x76543200,最后一位是x的最后一位0x000000EF,可否经过逻辑运算来分别获得呢?二进制
0x76543200:y1 = y & 0xffffff00 == 0x76543210 & 0xffffff00 = 0x76543200程序
0x000000EF:x1 = x & 0x000000ff == 0x89ABCDEF & 0x000000ff = 0x000000EF
最后两个结果(y1 + x1 或者使用按位或运算 x1 | y1两种方式都行)代码以下:
#include <stdio.h> int main(void) { int x, y; int x1, y1, r1; printf("Please is a x and y: "); scanf("%x %x", &x, &y); printf("x = %.8x and y = %.8x\n", x, y); x1 = x & 0x000000ff; y1 = y & 0xffffff00; //r1 = x1 + y1;//这种是相加的方法 r1 = x1 | y1;//这种仍是使用了逻辑运算按位或运算,相同位值有1的结果为1,否则结果为0 printf("x1 = %.8x and y1 = %.8x and r1 = %.8x\n", x1, y1, r1); return 0; }
2.43 只用位级和逻辑运算,编写出c表达式,在下列描述状况下产生1,而其余状况下获得0,你的代码应该能在因此字长的机器上运行,加上x是正数:
A. X的任何位都等于1 B. x的任何位都等于0 C. x的最低有效字节中的位都等于1 D. X的最低有效位的字节都等于0
答:位级和逻辑运算在上一题中已经回顾,分析如下四种状况:
A. X的任何位都等于1:这个可使用 按位或(|)运算来实现,好比x = 0x00000001 ===> x | 0xffffffff = 0xffffffff,或者使用取反再按位异或 ~x ^ x或者取反再按位或~x | x
B. X的任何位都等于0:使用按位异或,相同位0,反之为1,x ^ x
C. X的最低有效位字节位都为1:使用按位或运算或者算术右移运算
D. X的最低有效位字节位都为0:左移运算或者按位与运算
2.44 编写一个函数is_shifts_are_arithmetic(),使得这个函数在对整数使用算术右移的机器上运行时生成1,而其余状况下生成0,你的代码用该能够运行在任何字长的机器上。在几种机器上测试你的代码,编写并测试过程unsigned_shifts_are_arithmetic(),该过程肯定对无符号整数使用的位移形式。
答:分析一下:这道题主要考我们位移运算:左位移、右位移(正数与左位移同样,负数分为逻辑运算补0、算术运算补1)
第一种状况:算术右移的机器上边,经过算术右移获得结果1,设想一下算术右移,左边补齐有效位的是1,那么这时候该怎么办呢?1 = 0 + 1这个表达式熟悉吗?对,就是二进制补码,设想一下,神马状况下经过右移,能获得0呢?算术右移补的是1,那么假设我们先右移sizeof(int)位,获得的结果必然是全部的有效位都为1,怎么转换成0呢????有人想到取反,那你最后怎么加上1呢??那就是给右移后的数添加负号,仔细想一下,当全部有效位都是1的时候,添加一下负号,那结果会是什么???我们来计算一下它x的补码(补码 = ~x +1),那么结果就是咱们想要的
第二种状况:逻辑右移的机器上边,经过逻辑右移获得结果0,设想一下,什么状况下右移的结果会是0,很明显是当你右移到全部有效位都是0的时候,结果就为0了
基于上边的分析,什么状况下右移到整数结果所有为0呢??只有当右移sizeof(int)位,才能获得全为0(右移,逻辑运算,左边补0,右移几位截取掉几位,直到全部有效位都为0为止),因为程序须要通用,全部获得全部有效位全为0的数x,添加负号变成-x,我们来计算它的补码,-x = ~x + 1 = 0(好比是4位 -x = -0000 = 1111 + 1 = 10000,保留4位有效数字,最高位截取掉后,剩余有效位是0000)
2.45