首页 > 其他分享 >CSAPP 第二章 信息的表示与处理 教材习题

CSAPP 第二章 信息的表示与处理 教材习题

时间:2023-01-06 20:34:28浏览次数:38  
标签:CSAPP return int unsigned result 习题 第二章 sizeof size

要求不得使用条件语句、循环语句、分支语句、乘除法、取模运算、相对比较运算(\(<,>,\le,\ge\))。

2.58

int is_little_endian()
{
    unsigned int x = 1;
    unsigned char *start = (unsigned char *)(&x);
    return start[0];
}

2.59

(y >> 8 << 8) | (x & 0xFF)

2.60

unsigned replace_byte(unsigned x, int i, unsigned char b)
{
    int k = i * 8;
    return x ^ ((x >> k & 0xFF) << k) ^ (b << k);
}

2.61

A. !(~x)

B. !x

C. !(0xFF ^ (x & 0xFF))

D. !(0xFF ^ (x >> (w - 8) & 0xFF))


2.62

int shifts_are_arithmetic()
{
    int w = (sizeof(int)) << 3;
    int x = (-1) >> 1;
    return x >> (w - 1) & 1;
}

2.63

unsigned srl(signed x, int k)
{
    unsigned xsra = (int) x >> k;
    int w = (sizeof(int)) << 3;
    unsigned v = ~(-1 << (w - k)); 
    return xsra & v; // 只保留 xsra 的最低的 w - k 位即可。
}
int sra(int x, int k)
{
    int xsrl = (unsigned) x >> k;
    int w = (sizeof(int)) << 3;
    int sgn = (1 << (w - 1)) & x;
    int v = -1 << (w - k);
    v &= !sgn - 1; // 如果 x 为负,则 v 不变,如果 x 非负,则 v 变为 0。
    return xsrl | v;
}

2.64

int any_odd_one(unsigned x)
{
    unsigned v = 0x555555555;
    return !(!(x & v));
}

2.65

int odd_ones(unsigned x)
{
    x ^= x >> 1;
    x ^= x >> 2;
    x ^= x >> 4;
    x ^= x >> 8;
    x ^= x >> 16; // 此时得到的 x 的最低位是原来的 x 各个位置上的数字异或和的结果
    return x & 1;
}

2.66

int leftmost_one(unsigned x)
{
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16; // 此时得到的 x 形如 000...000111...111 且最高位 1 的位置和原来相同
    return x - (x >> 1);
}

2.67

A. 当左移位数大于等于机器字长时,此时进行的左移操作属于未定义行为,可能返回预期之外的结果。

B. 可以改为

int int_size_is_32() // works for w >= 32
{
    int t = 1 << 31;
    return t == -t;
}

C. 可以改为

int int_size_is_32() // works for w >= 16
{
    int t = 1 << 15;
    t <<= 15;
    t <<= 1;
    return t == -t;
}

2.68

int lower_one_mask(int n)
{
    unsigned x = (unsigned)(-1);
    int w = (sizeof(int)) << 3;
    return (int)(x >> (w - n)); // 这里要用逻辑右移
}

2.69

unsigned rotate_left(unsigned x, int n)
{
    int w = (sizeof(int)) << 3;
    return (x << n) | (x >> (w - n)); 
}

2.70

int fits_bits(int x, int n)
{
    // 判断 x 的前 w-n 位是否全为 0 或者全为 1 即可
    unsigned int v = (~0u) >> (w - n);
    int a = x & ((int)(v));
    v = ~v;
    int b = x | ((int)(v));
    return x == a || x == b;
}

2.71

A. 这段代码将抽取出的字节作为一个无符号数返回,而不是有符号数。

B. 正确的实现:

int xbyte(packed_t word, int bytenum)
{
		int x = (word >> (bytenum << 3)) & 0xFF;
  	x -= (x >> 7 & 1) << 8;
  	return x;
}

2.72

A. 因为 sizeof(val) 返回的是无符号数类型,计算 maxbytes-sizeof(val) 前会进行强制转换,进行的是无符号数减法,结果总是大于等于 0 的。

B. 将条件改为 if(maxbytes >= sizeof(val)) 即可。


2.73

int saturating_add(int x, int y)
{
    int w = (sizeof(int)) << 3;
    int TMin = 1 << (w - 1);
    int TMax = TMin - 1;
    int sum = x + y;
    int pos_overflow = !(x & TMin) && !(y & TMin) && (sum & TMin); // 用逻辑运算代替 if 语句
    int neg_overflow = (x & TMin) && (y & Tmin) && !(sum & TMin);
    pos_overflow && (sum = TMax); // 用短路特性代替 if 语句
    neg_overflow && (sum = TMin);
    return sum;
}

2.74

int sub_ok(int x, int y)
{
    int sub = x - y;
    int w = (sizeof(int)) << 3;
    int TMin = 1 << (w - 1);
    int pos_overflow = !(x & TMin) && (y & TMin) && (sub & TMin);
    int neg_overflow = (x & TMin) && !(y & TMin) && !(sub & TMin);
    return !(pos_overflow) && !(neg_overflow);
}

2.75

unsigned unsigned_high_prod(unsigned x, unsigned y)
{
    int w = (sizeof(int)) << 3;
    int v = signed_high_prod((int)(x), (int)(y));
    unsigned result = (unsigned)(v);
    result += (!(x >> (w - 1) & 1) - 1) & y;
    result += (!(y >> (w - 1) & 1) - 1) & x;
    return result;
}

2.76

void *calloc(size_t nmemb, size_t size) // 这里必然会用到乘法
{
    if (!nmemb || !size)
        return NULL;
    size_t bufsiz = nmemb * size;
    if (bufsiz / size == nmemb)
    {
        void *ptr = malloc(bufsiz);
        if (ptr != NULL)
            memset(ptr, 0, bufsiz);
        return ptr;
    }
    return NULL;
}

2.77

A. (x << 4) + x

B. x - (x << 3)

C. (x << 6) - (x << 2)

D. (x << 4) - (x << 7)


2.78

int divide_power2(int x, int k)
{
    int w = (sizeof(int)) << 3;
    int bias = (1 << k) - 1;
    int sgn = x >> (w - 1) & 1;
    bias &= (!sgn) - 1;
    return (w + bias) >> k;
}

2.79

int mul3div4(int x)
{
    x = (x << 1) + x;
    int bias = 3;
    int w = (sizeof(int)) << 3;
    bias &= !(x >> (w - 1) & 1) - 1;
    return (x + bias) >> 2;
}

2.80

题目的意思应该是计算 \(\frac 3 4 x\) 的值并向零舍入。

int threefourths(int x) // 分成前 30 位和后 2 位分别计算
{
    int w = (sizeof(int)) << 3;
    int a = x ^ (x & 3);
    int b = x & 3;
    int result = a >> 2;
    result += result << 1; // 前 30 位不存在舍入问题,先除再乘
    b += b << 1;
    b += (!(x >> (w - 1) & 1) - 1) & 3;
    b >>= 2; // 后 2 位不存在溢出问题,先乘再除
    result += b;
    return result;
}

2.81

A. (-1) << k

B. (unsigned)((-1) << (k + j)) >> k


2.82

A. 当 x 和 y 其中恰好有一者为 TMin 时,表达式为 0。

B. 总为 1,因为带符号的加减法与乘法满足交换律与结合律。

C. 总为 1,因为反码 = 补码 + 1。

D. 总为 1,因为类型转换时二进制编码不变。

E. 总为 1,因为算术右移是向下取整的。


2.83

A. 记这个无穷串的值为 \(x\) ,则 \(x\times 2^k-Y=x\) ,解得 \(x=\frac{Y}{2^k-1}\) 。

B. \((a).\frac{5}{7}\ (b).\frac{6}{15}=\frac{2}{5}\ (c).\frac{19}{63}\)


2.84

标签:CSAPP,return,int,unsigned,result,习题,第二章,sizeof,size
From: https://www.cnblogs.com/jklover/p/17031530.html

相关文章

  • 机器学习 吴恩达 第二章 笔记
    2.单变量线性回归(LinearRegressionwithOneVariable)  文字部分来自这位大佬的字幕合集2.1模型表示  我们的第一个学习算法是线性回归算法.在这段视频中,你会......
  • 使用嵌套的ScriptableObject及ReorderableList创建习题持久化数据
    使用嵌套的ScriptableObject及ReorderableList创建习题持久化数据效果展示题集持久化数据:存储题目,可以直接在inspector面板上创建对应的问题子项问题持久化数据:源码......
  • 天梯赛练习题L2(021-025)
    L2-021点赞狂魔如果有并列,则输出标签出现次数平均值最小的那个#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;typedefpair<LL,LL>PII;const......
  • 第二章 物理层
    目录(1)物理层的基本概念(2)数据通信2.1数据通信相关基本术语2.2三种通信方式2.3数据传输方式2.4码元2.5数字通信系统数据传输速率的两种表示方法2.6带宽(3)奈氏......
  • 习题2.5 两个有序链表序列的合并 (15 分)
    本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。函数接口定义:ListMerge(ListL1,ListL2);其中List结构定义如下:typedefstructNode......
  • 【加密与解密】第二章⑤
    2.别名执行的时候直接用内容替换原始操作数。别名有一种固定别名,另一种是自定义别名。有10个固定别名,为\(u0~\)u9.在定义固定别名时要用r命令,同时要在字母u前面加一个.......
  • 《DFZU2EG_4EV MPSoC之嵌入式Linux开发指南》第二章 Ubuntu系统入门​
    Ubuntu系统入门​在上一章我们已经安装好虚拟机,并且在虚拟机中安装好了Ubuntu操作系统了,本章我们就来学习Ubuntu系统的基本使用,通过本章的学习为我们以后的开发做准备。Ubun......
  • 第二章(类型)
    我们声明的变量是一个易于阅读的名字,用来表示这段内存。实际上,编译后的机器码不使用变量名,而是直接通过内存地址来访问目标数据。函数外声明变量,不能使用简短模式(go......
  • 天梯赛练习题L2(016-020)
    L2-016愿天下有情人都是失散多年的兄妹这题一开始我没有标注爸爸妈妈是男的是女的直接卡了半天#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;t......
  • HDLBits--Verilog习题记录5
    此题目较难,本文代码也是借鉴别人才完全理解。题目编号:verification:readingsimulations->buildacircuitfromasimulationwaveform->sequentialcircuit10题目描述......