@

实验要求

给出15个函数,规定了实现每个函数需要的逻辑和算术操作符(规定数量)。

只能使用规定的操作符! ˜ & ˆ | + << >>

1-12题不能使用循环或者条件语句

不能使用超过8位的常数(ff)

转载请注明出处:https://www.cnblogs.com/ustca/p/11740382.html

实现代码

1、pow2plus1

/*
* pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
*/
int pow2plus1(int x) {
/* exploit ability of shifts to compute powers of 2 */
return (1 << x) + 1;
}

2、pow2plus4

/*
* pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
*/
int pow2plus4(int x) {
/* exploit ability of shifts to compute powers of 2 */
int result = (1 << x);
result += 4;
return result;
}

3、bitXor

/*   bitXor - x^y using only ~ and &
* Example: bitXor(4, 5) = 1
* Legal ops: ~ &
* Max ops: 14
* Rating: 1
*/
int bitXor(int x, int y) {
return (~(x&y))&(~(~x&~y));//列出真值表
}

4、tmin

/*   tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void) {
return 1<<31;//0x80000000
}

5、isTmax

/*   isTmax - returns 1 if x is the maximum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTmax(int x) {
return !(x+x+2) & !!(~x);//x+1+x+1溢出并且非全一
//x: 0111 1111 1111 1111 1111 1111 1111 1111
//x+1: 1000 0000 0000 0000 0000 0000 0000 0000
//x+1+x: 1111 1111 1111 1111 1111 1111 1111 1111
//x+1+x+1:0000 0000 0000 0000 0000 0000 0000 0000
}

6、allOddBits

/*   allOddBits - return 1 if all odd-numbered bits in word set to 1
* where bits are numbered from 0 (least significant) to 31 (most significant)
* Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
int allOddBits(int x) {
x = (x>>16) & x;
x = (x>>8) & x;
x = (x>>4) & x;
x = (x>>2) & x;
return (x>>1)&1;
// &运算符的“归一性”
//1010 1010 1010 1010 1010 1010 1010 1010
//0000 0000 0000 0000 1010 1010 1010 1010
//0000 0000 0000 0000 0000 0000 1010 1010
//0000 0000 0000 0000 0000 0000 0000 1010
//0000 0000 0000 0000 0000 0000 0000 0010
// 可以反推理解:后四位四次翻转得第一行
// 只要倒数第二位为1成立,反推后所有的奇数位都为1
}

7、negate

/*   negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) {
return ~x+1; //带符号位取反加一即为相反数
}

8、isAsciiDigit

/*   isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
* Example: isAsciiDigit(0x35) = 1.
* isAsciiDigit(0x3a) = 0.
* isAsciiDigit(0x05) = 0.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 3
*/
int isAsciiDigit(int x) {
// 0x30 = 0011 0000b 0x39 = 0011 1001b
int a = (x>>4) ^ 0x3; // 判断5、6位是否全1
int b0 = (x>>3) & 1; // 判断第4位是否为1
int b1 = (x>>2) ^ 1; // 判断第3位是否为1
int b2 = (x>>1) ^ 1; // 判断第2位是否为1
return (!a) & ((!b0) | (b0&b1&b2));
// 如果5、6位全1 且 (4位为0或4位为1,2、3位为0)
}

9、conditional

/*   conditional - same as x ? y : z
* Example: conditional(2,4,5) = 4
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int conditional(int x, int y, int z) {
x = !x; // 将x设置为0或1
x = (x<<31)>>31; // 将x的0或1拓展到32位全0或全1
return (~x&y) | (x&z); // x为真则~x全1返回y,为假则x全1返回z
}

10、isLessOrEqual

/*   isLessOrEqual - if x <= y  then return 1, else return 0
* Example: isLessOrEqual(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isLessOrEqual(int x, int y) {
int z,s,sx,sy;
sx = (x>>31)&1; // 取x的符号位
sy = (y>>31)&1; // 取y的符号位
z = x + ~y + 1; // z = x-y
s = ((z>>31) & 1) | (!(z^0));
// 取z的符号位,s为真时x<y或者z全0(x==y)
return ((!(sx^sy))&s) | (sx&(!sy));
// xy同号且z<=0 或 x<=0 y>=0
}

11、logicalNeg

/*   logicalNeg - implement the ! operator, using all of
* the legal operators except !
* Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int logicalNeg(int x) {
// |运算符的“分裂性”
x |= x>>16; // 若高16位有1,则传递给低16位的对应位
x |= x>>8; // 若低16位的高8位有1,则传递给低8位的对应位
x |= x>>4; // 若低8位的高4位有1,则传递给低4位的对应位
x |= x>>2; // 若低4位的高2位有1,则传递给低2位的对应位
x |= x>>1; // 若低2位的高1位有1,则传递给最低1位
x ^= 1; // 只要x包含1,则必定会导致此时的x为1,x^=1即取反
return x&1;
}

12、howManyBits

/*  howManyBits - return the minimum number of bits required to represent x in
* two's complement
* Examples: howManyBits(12) = 5
* howManyBits(298) = 10
* howManyBits(-5) = 4
* howManyBits(0) = 1
* howManyBits(-1) = 1
* howManyBits(0x80000000) = 32
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 90
* Rating: 4
*/
int howManyBits(int x) {
int s,c1,c2,c3,c4,c5,c6;
int cnt = 0; // 计数
s = (x>>31)&1; // 符号位
x = ((s<<31)>>31) ^ x; // 取反x
s = !!(x>>16); // 判断高16位是否有1,有则s为1
c1 = s<<4; // 若高16位有1,则低16位可以计数16
x >>= c1; // 右移将已经计数的位移除,c1若为0,则用折半的长度判断
s = !!(x>>8); // 用8位的长度去判断,有效位的个数计入c2
c2 = s<<3;
x >>= c2;
s = !!(x>>4); // 用4位的长度去判断,有效位的个数计入c3
c3 = s<<2;
x >>= c3;
s = !!(x>>2); // 用2位的长度去判断,有效位的个数计入c4
c4 = s<<1;
x >>= c4;
s = !!(x>>1); // 用1位的长度去判断,有效位的个数计入c5
c5 = s;
x >>= c5;
c6 = !!x; // 判断最低位是否为1
cnt = c1+c2+c3+c4+c5+c6+1; // 将每次获得的低位有效位相加,再加1位符号位
return cnt;
}

13、floatScale2

/*   floatScale2 - Return bit-level equivalent of expression 2*f for
* floating point argument f.
* Both the argument and result are passed as unsigned int's, but
* they are to be interpreted as the bit-level representation of
* single-precision floating point values.
* When argument is NaN, return argument
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatScale2(unsigned uf) {
unsigned f = uf;
if ((f & 0x7F800000) == 0)// 如果阶码为0
f = ((f & 0x007FFFFF) << 1) | (0x80000000 & f);
// 尾数不为0则尾数左移1位,尾数第1位为1则阶码加1,尾数为0则uf为0返回0
else if ((f & 0x7F800000) != 0x7F800000)// 如果阶码不为0,且非全1
f = f + 0x00800000;// 阶码加1
return f;
}

14、floatFloat2Int

/*   floatFloat2Int - Return bit-level equivalent of expression (int) f
* for floating point argument f.
* Argument is passed as unsigned int, but
* it is to be interpreted as the bit-level representation of a
* single-precision floating point value.
* Anything out of range (including NaN and infinity) should return
* 0x80000000u.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
int floatFloat2Int(unsigned uf) {
unsigned INF = 1<<31; // INF = MaxInt+1
int e = (uf>>23) & 0xff;// 阶码
int s = (uf>>31) & 1; // 符号位
if (uf == 0) return 0;
uf <<= 8; // 左移保留至阶码最后1位
uf |= 1<<31; // 阶码最后一位设为1
uf >>= 8; // 高八位全0
e -= 127; // 阶数
if ((uf & 0x7f80000) == 0x7f80000 || e >= 32)
return INF; // 超过int范围返回INF
if (e < 0) // 小数返回0
return 0;
if (e <= 22) // 位数小于等于22位,尾数位右移
uf >>= 23-e;
else
uf <<= e-23; // 尾数大于22位,尾数为左移
if (s)
uf = ~uf + 1;// 若原uf为负数,则对此处的正数uf取反加1得其相反数
return uf;
}

15、floatPower2

/*   floatPower2 - Return bit-level equivalent of the expression 2.0^x
* (2.0 raised to the power x) for any 32-bit integer x.
*
* The unsigned value that is returned should have the identical bit
* representation as the single-precision floating-point number 2.0^x.
* If the result is too small to be represented as a denorm, return
* 0. If too large, return +INF.
*
* Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatPower2(int x) {
unsigned INF = 0xff << 23; // 阶码全1
int e = 127 + x; // 得到阶码
if (x < 0) // 阶数小于0直接返回0
return 0;
if (e >= 255) // 阶码>=255直接返回INF
return INF;
return e << 23;
// 直接将阶码左移23位,尾数全0,规格化时尾数隐藏有1个1作为底数
}

CSAPP: 位操作实现基本运算的更多相关文章

  1. 《CSAPP》实验一:位操作

    <CSAPP>号称程序员圣经,虽然中文译名为<深入理解计算机系统>,但其实没那么"深",只是覆盖面很广,一般用作计算机专业大一导论课的教科书.早就听闻书上配 ...

  2. CSAPP HITICS 大作业 hello's P2P by zsz

    摘 要 摘要是论文内容的高度概括,应具有独立性和自含性,即不阅读论文的全文,就能获得必要的信息.摘要应包括本论文的目的.主要内容.方法.成果及其理论与实际意义.摘要中不宜使用公式.结构式.图表和非公知 ...

  3. 系统级编程(csapp)

    系统级编程漫游 系统级编程提供学生从用户级.程序员的视角认识处理器.网络和操作系统,通过对汇编器和汇编代码.程序性能评测和优化.内存组织层次.网络协议和操作以及并行编程的学习,理解底层计算机系统对应用 ...

  4. [leetcode] 位操作题解

    子集 题目[78]:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 示例: 输入: nums = [1,2,3] 输出: [ [3],   [1],   [2],   [ ...

  5. CSAPP =1= 计算机系统漫游

    思维导图 预计阅读时间:15min 阅读书籍 <深入理解计算机系统> 参考视频 [精校中英字幕]2015 CMU 15-213 CSAPP 深入理解计算机系统 课程视频 参考文章 < ...

  6. CSAPP 之 DataLab 详解

    前言 本篇博客将会剖析 CSAPP - DataLab 各个习题的解题过程,加深对 int.unsigned.float 这几种数据类型的计算机表示方式的理解. DataLab 中包含下表所示的 12 ...

  7. 《Entity Framework 6 Recipes》中文翻译系列 (19) -----第三章 查询之使用位操作和多属性连接(join)

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 3-16  过滤中使用位操作 问题 你想在查询的过滤条件中使用位操作. 解决方案 假 ...

  8. 如何获取byte的各个bit值以及常见位操作

    项目中通过信号采集板的数据获取车上仪表盘指示灯的信息,将接收到的数据转成byte后,还要将每一个Byte的各个Bit值分离出来,这样才知道每个bit的值代表的具体信息.这里记录下如何获取byte的各个 ...

  9. php strtotime 在32位操作系统下的限制

    php strtotime 在32位操作系统下的限制 <?php class DateHelper{ /** * 在32位操作系统下,超过 2038-01-19 03:14:07 ,会溢出 * ...

随机推荐

  1. JDBC连接时出现的问题总结

    java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more tha ...

  2. 18 (OC)* RunTime

    目录: 一.怎么理解OC是动态语言,Runtime又是什么?二.理解消息机制的基本原理三.与Runtime交互的三种方式四.分析Runtime中的数据结构五.深入理解Rutime消息发送原理六.多继承 ...

  3. 操作DOM会影响WEB应用的性能

    平时在工作中,要优化自己开发的WEB应用的性能,一般是遵循以下几个原则: 1.减少网络请求. 2.压缩.合并静态资源文件,以此来减轻网络传输的带宽压力和资源消耗. 3.代码逻辑层面上的性能优化.比如减 ...

  4. [Pandas] 05 - Parallel processing

    相关资源 [Python] 09 - Multi-processing [Pandas] 01 - A guy based on NumPy [AI] 深度数学 - Bayes 这章非常有意思,但一定 ...

  5. 无法将类型为“System.Xml.XmlComment”的对象强制转换为类型“System.Xml.XmlElement”

    今天开发C#项目时,有一个需要读取XML的功能点.编码过程中遇到了如标题所示的异常,如下图所示: 查询官网后得知XmlComment是注释节点的类型,如下图所示: 于是得出结论,使用XmlDocume ...

  6. C# 代码往oracle数据库添加datetime格式列

    C# 代码往oracle数据库添加datetime格式列时,不需要在insert语句中为datetime类型使用to_date函数

  7. Python 爬虫监控女神的QQ空间新的说说,实现秒赞,并发送说说内容到你的邮箱

    这个文章主要是在前一篇文章上新增了说说秒赞的功能 前一篇文章可以了解一下 那么,这次主要功能就是 监控女神的 QQ空间,一旦女神发布新的说说,马上点赞,你的邮箱马上就会收到说说内容,是不是想了解一下 ...

  8. Spring 梳理-数据访问-DB

    针对接口编程 DAO是指数据访问对象(data access object),它提供了数据读取和写入到数据库中的一种方式.Spring认为,它应该以接口的方式发布功能,而应用程序的其他部分需要通过接口 ...

  9. 2.html5新布局元素

    1.html5的优点: ①对人友好,更加语义化,更直观,增加了代码的可读性. ②对计算机友好,浏览器更容易解析,搜索引擎更容易抓取文档内容. ③代码更加的简洁. 2.新增的布局标签: Article: ...

  10. 玩转 SpringBoot 2 快速整合拦截器

    概述 首先声明一下,这里所说的拦截器是 SpringMVC 的拦截器 HandlerInterceptor.使用SpringMVC 拦截器需要做如下操作: 创建拦截器类需要实现 HandlerInte ...