继续更新习题。

参考资料:

https://code.woboq.org/gcc/libiberty/calloc.c.html

https://dreamanddead.gitbooks.io/csapp-3e-solutions/content/

Chapter 2

81

#include <stdio.h>

int mode1(int k){
    int res = (-1) << k;

    return res;
}

int mode2(int k, int j){
    //产生1^(w-k)0^(k);
    int r1 = (-1) << (k);
    //产生0^(w-k)1^(k);
    int r2 = ~r1;
    //产生0^(w-k-j)1^(k)1^(j);
    int res = r2 << j;

    return res;
}

int main(){

    return 0;
}

82

A:

错误,反例是x=INT_MIN(不过这里vscode运行的结果感觉有点问题)

B:

正确,原因如下:

C:

正确,原因如下:

D:

左边:

右边:

E:

那么

所以

83

A:

利用等比级数求和即可,首项为$Y\times 2^{-k}$,公比为$2^{-k}$,所以无穷级数的和为

B:

(a)

(b)

(c)

84

分成两个版本,一个是if else版本,还有一个是只用逻辑表达式的版本:

#include <stdio.h>
#include <random>

unsigned f2u(float x){
    return *(unsigned *)&x;
}

int float_le_(float x, float y) {
    unsigned ux = f2u(x);
    unsigned uy = f2u(y);
    /* Get the sign bits */
    unsigned sx = ux >> 31;
    unsigned sy = uy >> 31;
    /* Give an expression using only ux, uy, sx, and sy */
    int res;
    //都为0
    if ((ux == (sx << 31)) && (uy == (sy << 31))){
        res = 1;
    }
    //不全为0
    if (sx != sy){//符号相反
        //负数小于正数
        res = sx > sy;
    }else{//符号相同
        if (sx){//负数反序
            res = ux >= uy;
        }else{//正数同序
            res = ux <= uy;
        }
    }

    return res;
}

int float_le(float x, float y) {
    unsigned ux = f2u(x);
    unsigned uy = f2u(y);
    /* Get the sign bits */
    unsigned sx = ux >> 31;
    unsigned sy = uy >> 31;
    /* Give an expression using only ux, uy, sx, and sy */
    //都为0
    int r1 = (ux == (sx << 31)) && (uy == (sy << 31));
    //一正一负, 负数小于正数
    int r2 = (sx != sy) && (sx > sy);
    //同号
    //负数情形
    int r3 = sx && (ux >= uy);
    //正数
    int r4 = (!sy) && (ux <= uy);
    //合并结果
    int res = r1 || r2 || r3 || r4;

    return res;
}

float randf(){
    return (rand() - (RAND_MAX / 2))  / (double) (RAND_MAX);
}

void test(){
    int n = 10000;
    for (int i = 0; i < n; i++){
        float x = randf();
        float y = randf();
        if ((x <= y) != float_le(x, y)){
            printf("Wrong answer for %f %f!\n", x, y);
            return;
        }
    }
    printf("Pass test!\n");
}

int main(){
    test();

    return 0;
}

85

浮点数表示:

A:

注意到

所以

那么

所以形式为:

0 10...01 110...0

B:

要得到最大奇数,必然有

所以形式为:

0 11...10 111...1

C:

首先找到最小规格化的数:

所以最小规格化的数为

倒数为

位级描述:

$f$的位级描述要复杂一些,不一定能直接表示。