csapp习题
2.14

做这道题之前先搞清楚~,!的作用和意义
~是按位取反,!是判断真假(注意,机器都是按照补码进行存储计算的,负数也算是真)
不懂的同学可以试一试下面的代码
#include
#include
using namespace std;
int main (void) {
int C;
while (scanf("%d",&C) != EOF) {
cout << "C = " << C << endl;
cout << "!C = " << !C << endl;
cout << "~C = " << ~C << endl;
}
return 0;
}
x= 0110 0110
y= 0011 1001 十六进制结果
x&y 0010 0000 0x20
x|y 0111 1111 0x7F
~x|~y 1101 1111 0xDF
x&!y 0110 0110
0000 0000 0x00
x&&y x||y 0x01
!x||!y 0x00
x&&~y 1100 0110
0x 01
2.58

忘记大端和小端可以看这篇
计算机存储的大端法和小端法_zuyi532的专栏-CSDN博客_大端法
借一张图

#include
int main()
{
int a = 0x12345678; //int是四字节
unsigned char *c = (unsigned char*)(&a);//char是1个字节
//int * p ;一个指针p ,又叫指针变量,指针变量就是存放的地址
//p 变量保存的地址所在内存单元中的数据类型为整型
//a是一个类型
//&a取a的地址
//(char *)&a 将a地址所在位置视为字符型指针的地址
if (*c == 0x78) //*c表示一个值
{ printf("1"); }
else { printf("0"); }
return 0;
}
2.27

两个unsigned类型的变量x和y,那么x,y都小于2的32次方。设x+y溢出为z,则z=x+y-2的32次方。则可以推出z-x=y-2的32次方。所以z-x<0,同理z-y<0。所以只要z int uadd_ok(unsigned x, unsigned y) { unsigned z = x + y; if(z < x) return 0; return 1; } 2.73 先了解一下溢出 正溢出:两个正数相加的结果超过了数据类型所能表示的最大范围,结果为负数 负溢出:两个负数相加的结果超过了数据类型所能表示的最小范围,结果为正数(包括0) int saturating_add(int x, int y) { //x,y为0,算数位移计算出的r为0xffffffff (补1) 计算出pos_of = 0xffffffff 对应tmax=0x7f..f //x,y为0xffffffff,r为0 对应tmin==0x80000000; 2.81 A 错误,寻找特殊情况,当x=0,y=tmin(-2^31)时,x>y,但-y依旧是tmin,并不会发生改变,-x>-y B 正确,整数左移5位相当于乘以32, C 错误, D 正确,这个等价于 (x-y)==-(y-x) 是永远成立的,无符号和有符号数的位级表示是相同的。 E 正确,最后一个bit清0,对于偶数是不变的,对于奇数相当于-1,而tmin是偶数,因此该减法不存在溢出情况。所以左边总是<=x。
int r = x + y;
int tmp = r;
int w = (sizeof(x) << 3) - 1;//31位
//x,y,r,取各自的符号位
x >>= w;
y >>= w;
r >>= w;
//正溢出时,只有一种情况满足
int pos_of = (~x)&(~y)&r;
//负溢出时,也只有一种情况满足
int neg_of = x & y & (~r);
//使用位运算
return (pos_of & TMAX) | (neg_of & TMIN) ;
}

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
