/* * fitsBits - return 1 if x can be represented as an *  n-bit, two's complement integer.0 otherwise*   Assume 1 <= n <= w*/
int fitsBits(int x, int n) {int r, c;c = 33 + ~n;r = !(((x << c)>>c)^x);return r;
}

这题真看不懂主要是因为an n-bit, two's complement integer,真不知道什么意思…

查了一下,其实就是n个位,用补码解释能够表示的范围大小,以 n = 4 为例

A 4-bit two’s complement number also represents 16 values: −8 to 7
位向量表示:-8 -> [1000] | 7 -> [0111]

以n = 3为例。
x = 3 -> [011] -> 3
x = -4 -> [100] -> -4
x = 5 -> [101] -> -3 (最高位为符号位,无法表示)

扩展到8位
x = 3 -> [0000 0011] -> 3
x = -4 -> [1111 1100] -> -4
x = 5 -> [0000 0101] -> 5

表示这些数字最小需要的位
x = 3 -> [011] -> 3
x = -4 -> [100] -> -4
x = 5 -> [0101] -> 5

也就是需要判断 n - 1 位 是不是符号位

第一种方式 (x<<w - n) >> w - n

以上面的例子得到
[0000 0011] -> 3
[1111 1100] -> -4
[1111 1101] -> -3 (因为5的最低符号位并不在n - 1位)

综上,只要进行移位以后再判断是否跟原数相同即可。

再来看答案

int fitsBits(int x, int n) {int r, c;c = 33 + ~n;r = !(((x << c)>>c)^x);return r;
}
c = 33 + ~n
# 分解成
c = 32 + (~n + 1)

取反+1的操作很容易想到得到补码的负数,如n = 3 (8 位表示)

3 => [0000 0011]
(~3) + 1 => [1111 1101] => -3

其实这个操作相当于

c = 33 + ~n =>  c = 32 - n

之前说过进行移位运算
(x<<w - n) >> w - n 这里w = 32

再看这一行

r = !(((x << c)>>c)^x);

我们经常用!(x ^ y) 判断两数是否相等,相等返回1,不相等返回0

!(0 ^ 0) //=> 1
!(1 ^ 0) //=> 0

实际上就是判断经过移位的数是否跟原来的数相等,从而判断符号位的位置。


另一种思路

扩展到8位
x = 3 -> [0000 0011] -> 3
x = -4 -> [1111 1100] -> -4
x = 5 -> [0000 0101] -> 5

扩展以后高w - n + 1位,要么为0,要么为-1

右移两位,>> n - 1
x = 3 -> [0000 0000] -> 0
x = -4 -> [1111 1111] ->-1
x = 5 -> [0000 0001] -> 1

如果右移结果为0/-1就返回1,其他返回0

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

or

int fits_bits(int x, int n){x >>= (n-1);return !x || !(~x);
}

参考文章:
https://blog.csdn.net/zhanyu1990/article/details/24936663
https://stackoverflow.com/questions/42790409/bitwise-operation-fitsbits

CSAPP 第二章家庭作业2.70相关推荐

  1. CSAPP第二章家庭作业参考答案

    (CSAPP第三版系列)导航篇传送门 2.56 用不同的示例值运行show_bytes的代码. #include <stdio.h>typedef unsigned char *byte_ ...

  2. 20135202闫佳歆-第二章家庭作业-2.69

    第二章家庭作业 选题:2.69 分值:三分 作业过程: 以下是rotate_right函数的代码: unsigned rotate_right(unsigned x, int n) {int endb ...

  3. 深入理解计算机系统_3e 第二章家庭作业 CS:APP3e chapter 2 homework

    初始完成日期:2017.9.26 许可:除2.55对应代码外(如需使用请联系 randy.bryant@cs.cmu.edu),任何人可以自由的使用,修改,分发本文档的代码. 本机环境: (有一些需要 ...

  4. HTML网页作业第二章课后作业,泵与泵站-第二章-课后作业.ppt

    泵与泵站-第二章-课后作业 作业: 1.如图2-104所示的泵装置.泵从一个密闭水箱抽水,输入另一个密闭水箱,水箱内的水面与泵轴平齐,试问: (1)该泵装置的静杨程HST=?(m)22 (2)泵的吸水 ...

  5. 深入理解计算机系统(CSAPP) 第二章

    家庭作业 2.57 借助 C++ 模板可以很方便的实现. // g++ -o main main.cc -std=c++11 #include <string> #include < ...

  6. 算法设计与分析第二章课后作业

    第二章 一.单选题 1 [单选题]给定字符集{a,b,c,d,e,f},若用定长码编码,至少需要几位二进制位() A.1位 B.2位 C.3位 D.4位 正确答案: C 我的答案:C 得分: 5.0分 ...

  7. CSAPP第八、九章家庭作业(原书第二版)

    答:到达第一个Fork()函数时,创建一个子进程,此时由于还没有调用过exit函数,故此时atexit函数此时还不会被调用,等待exit函数调用才打印2.第二个Fork()由创建一个子进程,此时有4个 ...

  8. CSAPP第七章家庭作业(原书第二版)

    7.6 buf前加了extern是外部符号,由main.c定义,故定义符号的模块是main.o,是int型变量,属于.data节:bufp0和swap函数前未加extern和static,故是全局符号 ...

  9. CSAPP第89章家庭作业(部分)

    画出进程图: 原则如下: (1) 遇到fork函数就分支,每个水平的箭头对应于从 左到右执行指令的进程,而每个垂直的箭头对应于 fork 函数的执行 (2) 分支的时候专注于父进程执行完,再处理另一个 ...

最新文章

  1. BNUOJ34980方(芳)格(哥)取数(好坑)
  2. DroidPilot 测试脚本详解 (一)
  3. iOS学习笔记(1)--认识Xcode6.1的Interface Builder和常用快捷键
  4. [转]MSDN - 在客户端脚本中为 UpdateProgress 控件编程
  5. 16位汇编 loop循环
  6. 双机/RAC/Dataguard的区别【转】
  7. virtualbox android分辨率,VirtualBox 修改Android x86虚拟机的分辨率
  8. Electron学习笔记(一) 配置, 创建, 设置, 监听
  9. 《数据库原理与应用》课程实验报告三 --数据库的嵌套查询
  10. Multifactor Explanations of Asset Pricing Anomalies学术翻译
  11. 理解Linux的平均负载和性能监控
  12. ROS实验笔记之——SLAM无人驾驶初入门
  13. 开源Api后台服务/管理系统 HoServer
  14. H264系列(5):关于ITU-H264 和 ISO/IEC H264 的关系
  15. 架构探险-轻量级微服务架构_第3部分-单活动架构+一些时髦的Dagger
  16. 菲中工商贸投资合作签约活动在京举办
  17. windows server + documents4j 转excel报错 Could not access target file
  18. 《连线》杂志:Web已死 Internet永生(全文),互联网营销
  19. Java 常用图片处理合集
  20. 移动宽带内网穿透教程,快解析nat版快速实现

热门文章

  1. 华为认证HCIA-Datacom知识点
  2. cocos shader 之 黑白滤镜
  3. 飞书会议视频会议系统,会议场景全hold住
  4. 显著目标检测:IVIF
  5. 【附源码】Python计算机毕业设计社区志愿者管理系统
  6. 【iOS】—— 懒加载
  7. 对抗样本生成算法复现代码解析:FGSM和DeepFool
  8. GPS接收机-从射频信号到定位解算
  9. docker搭建mongodb高可用集群
  10. SRAM随机存储器的特点及结构