CSAPP 第二章家庭作业2.70
/* * 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相关推荐
- CSAPP第二章家庭作业参考答案
(CSAPP第三版系列)导航篇传送门 2.56 用不同的示例值运行show_bytes的代码. #include <stdio.h>typedef unsigned char *byte_ ...
- 20135202闫佳歆-第二章家庭作业-2.69
第二章家庭作业 选题:2.69 分值:三分 作业过程: 以下是rotate_right函数的代码: unsigned rotate_right(unsigned x, int n) {int endb ...
- 深入理解计算机系统_3e 第二章家庭作业 CS:APP3e chapter 2 homework
初始完成日期:2017.9.26 许可:除2.55对应代码外(如需使用请联系 randy.bryant@cs.cmu.edu),任何人可以自由的使用,修改,分发本文档的代码. 本机环境: (有一些需要 ...
- HTML网页作业第二章课后作业,泵与泵站-第二章-课后作业.ppt
泵与泵站-第二章-课后作业 作业: 1.如图2-104所示的泵装置.泵从一个密闭水箱抽水,输入另一个密闭水箱,水箱内的水面与泵轴平齐,试问: (1)该泵装置的静杨程HST=?(m)22 (2)泵的吸水 ...
- 深入理解计算机系统(CSAPP) 第二章
家庭作业 2.57 借助 C++ 模板可以很方便的实现. // g++ -o main main.cc -std=c++11 #include <string> #include < ...
- 算法设计与分析第二章课后作业
第二章 一.单选题 1 [单选题]给定字符集{a,b,c,d,e,f},若用定长码编码,至少需要几位二进制位() A.1位 B.2位 C.3位 D.4位 正确答案: C 我的答案:C 得分: 5.0分 ...
- CSAPP第八、九章家庭作业(原书第二版)
答:到达第一个Fork()函数时,创建一个子进程,此时由于还没有调用过exit函数,故此时atexit函数此时还不会被调用,等待exit函数调用才打印2.第二个Fork()由创建一个子进程,此时有4个 ...
- CSAPP第七章家庭作业(原书第二版)
7.6 buf前加了extern是外部符号,由main.c定义,故定义符号的模块是main.o,是int型变量,属于.data节:bufp0和swap函数前未加extern和static,故是全局符号 ...
- CSAPP第89章家庭作业(部分)
画出进程图: 原则如下: (1) 遇到fork函数就分支,每个水平的箭头对应于从 左到右执行指令的进程,而每个垂直的箭头对应于 fork 函数的执行 (2) 分支的时候专注于父进程执行完,再处理另一个 ...
最新文章
- BNUOJ34980方(芳)格(哥)取数(好坑)
- DroidPilot 测试脚本详解 (一)
- iOS学习笔记(1)--认识Xcode6.1的Interface Builder和常用快捷键
- [转]MSDN - 在客户端脚本中为 UpdateProgress 控件编程
- 16位汇编 loop循环
- 双机/RAC/Dataguard的区别【转】
- virtualbox android分辨率,VirtualBox 修改Android x86虚拟机的分辨率
- Electron学习笔记(一) 配置, 创建, 设置, 监听
- 《数据库原理与应用》课程实验报告三 --数据库的嵌套查询
- Multifactor Explanations of Asset Pricing Anomalies学术翻译
- 理解Linux的平均负载和性能监控
- ROS实验笔记之——SLAM无人驾驶初入门
- 开源Api后台服务/管理系统 HoServer
- H264系列(5):关于ITU-H264 和 ISO/IEC H264 的关系
- 架构探险-轻量级微服务架构_第3部分-单活动架构+一些时髦的Dagger
- 菲中工商贸投资合作签约活动在京举办
- windows server + documents4j 转excel报错 Could not access target file
- 《连线》杂志:Web已死 Internet永生(全文),互联网营销
- Java 常用图片处理合集
- 移动宽带内网穿透教程,快解析nat版快速实现