# CSAPP3e-第二章Homework

## 2.58

int isLittleEndian1()
{
int a = 1;
return ((char*)&a)[0];
}

## 2.59

int f2_59(int x, int y)
{
return x&(((1<<(sizeof(int)-1)*8)-1)<<8)|(y&0xFF);
}

## 2.60

unsigned replaceByte(unsigned x, int i, unsigned char b)
{
int t = ~0 - ((1LL<<(i+1<<3))-(1<<(i<<3)));
return x&t|((unsigned)b<<(i<<3));
}

## 2.61

int A2_61(int x)
{
return !(x^~0);
}
int B2_61(int x)
{
return !x;
}
int C2_61(int x)
{
return !((x&0xFF)^0xFF);
}
int D2_61(int x)
{
return !((unsigned)x>>((sizeof(int)-1)<<3));
}

## 2.62

int isRightShiftAreArithmetic()
{
int x = -1>>1;
return x==-1;
}

## 2.63

unsigned srl(unsigned x, int k)
{
unsigned xsra = (int)x>>k;
return xsra&(1<<(sizeof(int)<<3)-k)-1;
}
int sra(int x, int k)
{
int xsrl = (unsigned)x>>k;
int t = ~0-(1<<k)+1 & x>>((sizeof(int)<<3)-1);
return t|xsrl;
}

## 2.64

//题目中没有说bit从0开始计数还是从1开始，此处默认从0开始
int anyOddOne(unsigned x)
{
return (x&0xaaaaaaaa)==0xaaaaaaaa;
}

## 2.65

int oddOnesV1(unsigned x)
{
//思路，用xor消掉成对的1，不成对的记录下来
x ^= x<<16;
x ^= x<<8;
x ^= x<<4;
x ^= x<<2;
x ^= x<<1;
return x>>31;
}
int oddOnesV2(unsigned x)
{
//思路与上一个函数类似
x ^= x<<1;  //思考的时候只考虑奇数位，不需要考虑偶数位（从1开始计数bit位）
x ^= x<<2;  //只考虑mod4==0的位置
x ^= x<<4;  //只考虑mod8==0的位置
x ^= x<<8;  //只考虑mod16==0的位置
x ^= x<<16; //只考虑mod32==0的位置
return x>>31;
}

## 2.66

int leftMostOne(unsigned x)
{
x |= x>>1;
x |= x>>2;
x |= x>>4;
x |= x>>8;
x |= x>>16;
return x-(x>>1);
}

## 2.67

int intSizeIs32()
{
return INT_MAX==0x80000000-1;
}

## 2.68

int lowerOneMark(int n)
{
int t = -!(n-(sizeof(int)<<3)); //方法1
return (1<<n)-1&~t | t;
//  return ((n!=(sizeof(int)<<3))<<n)-1;    //方法2
}

## 2.69

unsigned rotateLeft(unsigned x, int n)
{
//移位sizeof*8不行，但是移位sizeof*8-1再移位1就可行了，上一题也可以这样搞
return x>>((sizeof(unsigned)<<3)-n-1)>>1 | x<<n;
}

## 2.70

int fitBits(int x, int n)
{
return x>>n-1==0 | x>>n-1==-1;
}

## 2.71

typedef unsigned pack_t;
int xbyte(pack_t word, int bytenum)
{
return (int)word<<(3-bytenum<<3)>>24;
}

## 2.73

int saturatingAdd(int x, int y)
{
//方法一
int t = (sizeof(int)<<3)-1;
int p = ((unsigned)x>>t)+((unsigned)y>>t)+((unsigned)x+y>>t);
t = ((unsigned)x>>t)+((unsigned)y>>t);
return -(p==2&&t!=1)&INT_MIN | -(p==1&&t!=1)&INT_MAX | -(p==0||t==1)&x+y | -(p==3||t==1)&x+y;

//方法二
int t = (sizeof(int)<<3)-1;
int p = ((unsigned)x>>t<<2)|((unsigned)y>>t<<1)|((unsigned)x+y>>t);
return -(p==6)&INT_MIN | -(p==1)&INT_MAX | -(p!=1&&p!=6)&x+y;

//方法三（from http://blog.csdn.net/yang_f_k/article/details/8857904）
int w=sizeof(int)<<3;
int sum = x+y;

int neg_of = x_lmb && y_lmb && (!sum_lmb);
int pos_of = !x_lmb && !y_lmb && sum_lmb;

(pos_of &&(sum=INT_MAX)) || (neg_of && (sum = INT_MIN)); //这一条不错
return sum;
}

## 2.74

int tsubOk(int x, int y)
{
int t = (sizeof(int)<<3)-1;
int p = (unsigned)x>>t<<2 | (unsigned)-y>>t<<1 | (unsigned)x-y>>t;
t = y==INT_MIN;
return p!=6 && p!=1 && !t || t && p==6;
}

## 2.75

unsigned unsignedHightProd(unsigned x, unsigned y)
{
unsigned t = signed_high_prod(x, y);
int l = (sizeof(int)<<3)-1;
return t + (x>>l)*x+(y>>l)*y;
}

## 2.76

void* Calloc(size_t nmemb, size_t size)
{
size_t t = nmemb*size;
void *p;
if(!size || t/size==nmemb){
p = malloc(t);
if(!p)return NULL;
memset(p, 0, t);
}else return NULL;
return p;
}

## 2.77

int f2_77(int x)
{
int k1 = (x<<4)+x;
int k2 = -(x<<3)+x;
int k3 = (x<<6)-(x<<2);
int k4 = -(x<<7)+(x<<4);
return (k1==x*17)<<3 | (k2==x*-7)<<2 | (k3==x*60)<<1 | k4==x*-112;
}

## 2.78

int dividePower2(int x, int k)
{
int l = sizeof(int)<<3;
l = -(x>>l-1)//;
return (l<<k)-l+x >> k;
}

## 2.79

int mul3div4(int x)
{
x = (x<<2) - x;
int l = sizeof(int)<<3;
int t = -(x>>l-1);
return (t<<2)-t+x >> 2;
}

## 2.80

int threefourths(int x)
{
int t = x&0x3;
int t2 = -(x>>(sizeof(int)<<3)-1);
int p = (x>>2);
p = (p<<1)+p;
t = (t<<1)+t;
p += (t>>2) + (t2&&t);
return p;
}

## 2.81

int hw281A(int k)
{
return 0-(1<<k-!!k<<!!k);   //k may equal to 0 or 32;
}

int hw281B(int j, int k)
{
int t = k+j;
return (0-(1<<j-!!j<<!!j)) ^ (0-(1<<t-!!t<<!!t));
}

## 2.82

/*
* A: NO; x== 0x10000000, B==rand();
* B: Yes;
* C: Yes; 因为，取反操作之后立刻截断与计算完之后再截断是等价的。
* 可以两边都加上1，从而左右两个过程（截断之前）都是两个负数相加
* D: Yes;
* E: Yes;
*/

## 2.83

i=1Y×2ki$\sum_{i=1}^{\infty}Y\times2^{-k*i}$

## 2.84

return ((sx<sy) && ux!=0 && uy!=0x80000000) | (sx==sy) & !!(ux-uy);