《CSAPP》(第3版)答案(第二章)(二)

P70

#include <stdio.h>
int fits_bits(int x,int n){
    int w=sizeof(int)<<3;
    return x == x<<(w-n)>>(w-n);
}
int main(){
    printf("%d\n",fits_bits(114514,19));
}

P71

  • A
    这个函数不能从word中提取一个负值的byte。
  • B
#include <stdio.h>
typedef unsigned packed_t;
int xbyte(packed_t word,int bytenum){
    int w = sizeof(unsigned);
    int left = (w-bytenum-1)<<3;
    int right = (w-1)<<3;
    return (int)(word<<left>>right);
}
int main(){
    printf("%d\n",xbyte(-114514,0));
}

P72

  • A
    sizeof返回的值类型是unsigned,所以maxbytes-sizeof(val)的值也是unsigned类型,大于等于0恒成立。
  • B
#include <stdio.h>
void copy_int(int val,void* buf,int maxbytes){
    if(maxbytes-(int)sizeof(val)>=0)
        memcpy(buf,(void*)&val,sizeof(val));
}
int main(){
    int max = 114;
    void* buff = malloc(max);
    copy_int(514,&buff,114);
}

P73

#include <stdio.h>
#include <limits.h>
int saturating_add(int x,int y){
    int sum = x+y;
    int mask = INT_MIN;
    int pos_over = !(x&mask)&&!(y&mask)&&(sum&mask);
    int neg_over = (x&mask)&&(y&mask)&&!(sum&mask);
    (pos_over&&(sum=INT_MAX))||(neg_over&&(sum=INT_MIN));//这段是求教大佬得到的,实在精妙
    return sum;
}
int main(){
    printf("%x\n",saturating_add(0x10000000,-1));
}

P74

#include <stdio.h>
#include <limits.h>
int tsub_ok(int x,int y){
    int sub = x-y;
    return !((x>0&&y<0&&sub<0)||(x<0&&y>0&&sub>0));
}
int main(){
    printf("%d\n",tsub_ok(114514,INT_MIN));
}

P75

#include <stdio.h>
#include <inttypes.h>
int signed_high_prod(int x, int y) {
  int64_t mul = (int64_t) x * y;
  return mul >> 32;
}
unsigned unsigned_high_prod(unsigned x, unsigned y) {
  int sig_x = x >> 31;
  int sig_y = y >> 31;
  int signed_prod = signed_high_prod(x, y);
  return signed_prod + x * sig_y + y * sig_x;
}
unsigned test(unsigned x, unsigned y) {
  uint64_t mul = (uint64_t) x * y;
  return mul >> 32;
}
int main(){
    printf("%d\n",test(114514,1919810)==unsigned_high_prod(114514,1919810));
}

P76

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
void* mcalloc(size_t nmemb,size_t size){
    if(nmemb==0||size==0)
        return NULL;
    int tmp = nmemb*size;    
    if(nmemb==tmp/size){//注意不能与上一行合并写成nmemb==(nmemb*size)/size
        void* p = malloc(size);
        if(p)
            memset(p,0,nmemb);
        return p;    
    } 
    return NULL; 
}
int main(){
    printf("%d\n",mcalloc(INT_MAX,INT_MAX));
}

P77

#include <stdio.h>
int mul17(int x){
    return (x<<4)+x;
}
int mulm7(int x){
    return x-(x<<3);
}
int mul60(int x){
    return (x<<6)-(x<<2);
}
int mulm112(int x){
    return (x<<4)-(x<<7);
}
int main(){
    printf("%d\n",mul17(114514)==17*114514);
    printf("%d\n",mulm7(114514)==(-7)*114514);
    printf("%d\n",mul60(114514)==60*114514);
    printf("%d\n",mulm112(114514)==(-112)*114514);
}

P78

#include <stdio.h>
#include <limits.h>
int divide_power2(int x,int k){
    int sig = x&INT_MIN;
    (sig&&(x=x+(1<<k)-1));
    return x>>k;
}
int main(){
    printf("%d\n",divide_power2(-114514,3)==(-114514)/8);
}

P79

#include <stdio.h>
#include <limits.h>
int divide_power2(int x,int k){
    int sig = x&INT_MIN;
    (sig&&(x=x+(1<<k)-1));
    return x>>k;
}
int mul3div4(int x){
    x = (x<<1)+x;
    return divide_power2(x,2);
}
int main(){
    printf("%d\n",mul3div4(114514)==114514*3/4);
}

P80

#include <stdio.h>
#include <limits.h>
int threeforths(int x) {
  int sig = x & INT_MIN;
  int head = x & ~0x3;
  int tail = x & 0x3;
  int hdd4 = head >> 2;
  int hdd4m3 = (hdd4 << 1) + hdd4;
  int tlm3 = (tail << 1) + tail;
  int bias = (1 << 2) - 1;
  (sig && (tlm3 += bias));
  int tlm3d4 = tlm3 >> 2;
  return hdd4m3 + tlm3d4;
}
int main(int argc, char* argv[]) {
    printf("%d\n",threeforths(-3)==-2);
}

P81

  • A
#include <stdio.h>
int patternGenerator(int k){
    return (-1<<k);
}
int main(){
    printf("%x\n",patternGenerator(8));
}
  • B
#include <stdio.h>
int patternGenerator(int k,int j){
    return (~((-1)<<k))<<j;//运算符优先级真的坑
}
int main(){
    printf("%x\n",patternGenerator(16,8));
}

P82

  • A
    不是。x=INT_MIN
  • B
    是(即答
  • C
  • D
  • E

P83

  • A
    Y 2 k 1 \frac{Y}{2^{k}-1}
  • B
    a. 5 7 \frac{5}{7}
    b. 2 5 \frac{2}{5}
    c. 19 63 \frac{19}{63}

P84

#include <stdio.h>
unsigned f2u(float x){
    return *(unsigned*)&x;
}
int float_le(float x,float y){
    unsigned ux = f2u(x);
    unsigned uy = f2u(y);
    unsigned sx = ux>>31;
    unsigned sy = uy>>31;
    return (ux<<1==0&&uy<<1==0)||
        (sx&&!sy)||
        (!sx&&!sy&&ux<=uy)||
        (sx&&sy&&ux>=uy);
}
int main(){
    printf("%d\n",float_le(-0,+0));
    printf("%d\n",float_le(+0,-0));
}

此段代码非原创,参见https://github.com/DreamAndDead/CSAPP-3e-Solutions/issues/1

发布了94 篇原创文章 · 获赞 69 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/swy_swy_swy/article/details/105076817