这是一个关于机器级的整数、浮点数表示和位运算的实验。要求用给定的操作符、尽可能少的操作数去实现对应的函数功能。

完整的实验包:链接: https://pan.baidu.com/s/1xUBi3XDlidPQFNexbjXoLw 密码: 2333

以下是全部函数的代码:

  1. /*****************************计算log2(x)向下取整*******************************/
  2. int ilog2(int x) {
  3. int bit_16, bit_8, bit_4, bit_2, bit_1;
  4. bit_16 = (!!(x >> )) << ; //如果x >> 16非零,则至少有16位
  5. x = x >> bit_16;
  6. bit_8 = (!!(x >> )) << ;
  7. x = x >> bit_8;
  8. bit_4 = (!!(x >> )) << ;
  9. x = x >> bit_4;
  10. bit_2 = (!!(x >> )) << ;
  11. x = x >> bit_2;
  12. bit_1 = x >> ; //还剩两位时,直接判断首位。bit_1 == 1,剩两位;bit_1 == 0,剩一位
  13. return bit_16 + bit_8 + bit_4 + bit_2 + bit_1;
         //实际是(bit_1 + 1)-1;由于向下舍入,总位数减一
  14. }
  15.  
  16. /****************************表达x所需要的最少位数******************************/
  17. int howManyBits(int x) {
  18. int bit_16, bit_8, bit_4, bit_2, bit_1, result;
  19. int k = x >> ;
  20. int temp = x ^ k;
         //x为正,temp = x;x为负,temp = ~x
  21. int isZero = (!!(temp << )) >> ;
         //x = 0或x = -1时,temp = 0,isZero = 0...0;否则isZero = 1...1
  22. bit_16 = (!!(temp >> )) << ;
  23. temp = temp >> bit_16;
  24. bit_8 = (!!(temp << )) << ;
  25. temp = temp >> bit_8;
  26. bit_4 = (!!(temp << )) << ;
  27. temp = temp >> bit_4;
  28. bit_2 = (!!(temp << )) << ;
  29. temp = temp >> bit_2;
  30. bit_1 = temp >> ;
  31. result = bit_16 + bit_8 + bit_4 + bit_2 + bit_1 + ;
          //真正位数为bit_16 + ... + bit_1 + 1,再加符号位一位
  32. return (!isZero) | (result & isZero);
  33. }
  34.  
  35. /************************************逻辑右移*************************************/
  36. int logicshift(int x, int n)
  37. {
  38. int temp = ~( << );
  39. temp = ((temp >> n) << ) + ; //生成掩码0...01...1(前面为n个0)
  40. return (x >> n) & temp;
  41. }
  42.  
  43. /*************************类似于c语言中的x ? y : z**********************************/
  44. int conditional(int x, int y,int z)
  45. {
  46. int temp = (~(!x)) + ; //要在return中完成,必须生成x,y的掩码
  47. return (temp & z) | ((~temp) & y); //当x = 0时,temp = 1...1;当x != 0时,temp = 0...0
  48. }
  49.  
  50. /*********************************** x/ 2^n *****************************************/
  51. int divpwr2(int x, int n)
  52. {
  53. int temp = ( << n) + (~); //temp为baising(偏置),1...1(共n个1)
  54. return (x + ((x >> ) & temp)) >> n; //只有负数才要加偏置,所以temp要与符号位相与
  55. }
  56.  
  57. /****************************** x < y ? ***********************************/
  58. int isLessOrEqual(int x, int y)
  59. {
  60. int signx = x >> ;
  61. int signy = y >> ;
  62. int signEqual = (!(signx ^ signy) & ((x + (~y)) >> ));//符号位不同时,做差
  63. int signDiffer = signx & (!signy); //符号位相同,直接比较符号位
  64. return signEqual | signDiffer;
  65. }
  66.  
  67. /**********************操作数更小的版本**************************/
  68. int isLessOrEqual_2(int x, int y)
  69. {
  70. int not_y = ~y;
  71. return ((((x + not_y) & (x ^ not_y)) | (x & not_y)) >> ) & ;
  72. // x-y-1<0 <----------x,y不同号------>x为负,y为正,才为正
  73. }
  74.  
  75. /****************************不用负号得到-x*********************************/
  76. int negate(int x)
  77. {
  78. return ~x + ; //按位取反,末位加一
  79. }
  80.  
  81. /**********************返回最小的补码***************************************/
  82. int tmin(void)
  83. {
  84. return << ;
  85. }
  86.  
  87. /*************************只用~ 和 | 实现x&y*****************************/
  88. int bitAnd(int x, int y)
  89. {
  90. return ~(~x | y); //摩根律
  91. }
  92.  
  93. /**************************从字x中取出第n个字节*********************************/
  94. int getByte(int x, int n)
  95. {
  96. return (x >> (n << )) & 0xff; //是从0开始数的
  97. }
  98.  
  99. /*********************************计算x中1的数目*********************************/
  100. int bitCount(int x)
  101. {
  102. int result;
  103. int tmpmark1 = 0x55 + (0x55 << ); //最大0xff
  104. int mark1 = tmpmark1 + (tmpmark1 << );
  105. int tmpmark2 = 0x33 + (0x33 <<);
  106. int mark2 = tmpmark2 + (tmpmark2 << );
  107. int tmpmark3 = 0x0f + (0x0f << );
  108. int mark3 = tmpmark3 + (tmpmark3 << );
  109. int mark4 = 0xff + (0xff << );
  110. int mark5 = 0xff + (0xff << ); //以上生成5个掩码
  111.  
  112. result = (x & mark1) + ((x >> ) & mark1);
  113. result = (result & mark2) + ((result >> ) & mark2); //这两个由于进位问题,不能先加再与
  114. result = (result + (result >> )) & mark3; //分治
  115. result = (result + (result >> )) & mark4;
  116. result = (result + (result >> )) & mark5;
  117. return result;
  118. }
  119.  
  120. /***************************计算uf/2*********************************/
  121. unsigned float_half(unsigned uf)
  122. {
  123. unsigned s = uf & 0x80000000;
  124. unsigned exp = uf & 0x7f800000;
  125. int lsb = ((uf & ) == ); //判断frac最后两位是否为11
  126. if (exp == 0x7f800000)
  127. return uf;
  128. else if (exp <= 0x800000)
  129. return s | (((uf ^ s) + lsb) >> ); //uf^s将符号位置零,uf^s = frac + exp末位
  130. else
  131. return uf - 0x800000; //整体思路就是模拟
  132. }
  133.  
  134. /****************************计算(float)x***********************************/
  135. int float_f2i(unsigned uf)
  136. {
  137. int abs;
  138. int sign = uf >> ;
  139. int exp = (uf >> ) & 0xff;
  140. int frac = uf & 0x007fffff;
  141. if (exp < 0x7f) return ;
  142. if (exp > ) return 0x80000000; //Tmax = 2^31 -1
  143.  
  144. abs = ((frac >> ) + ) << (exp - ); //模拟
  145. if (sign)
  146. return -abs;
  147. else
  148. return abs;
  149. }
  150.  
  151. /****************************计算2*f***************************************/
  152. unsigned float_twice(unsigned uf)
  153. {
  154. int result;
  155. int exp = uf & 0x7f800000;
  156. int frac = uf & 0x7fffff;
  157. if (exp == 0x7f800000)
  158. return uf;
  159. else if (exp == )
  160. frac = frac << ; //frac也可用uf代替,因为此时frac = uf
  161. else
  162. exp = exp + 0x800000;
  163. result = (uf & 0x80000000) | exp | frac;
  164. return result;
  165. }

CSAPP lab1 datalab-handout的更多相关文章

  1. CSAPP:Lab1 -DataLab 超详解

    写在前面 之前考研的时候csapp的书有刷过5,6遍,所以对书本知识还算比较了解.恰逢最近在学c++的时候,顺带刷一下大名鼎鼎的csapp实验. 0. 环境准备 最好准备一个纯净的Linux系统这里建 ...

  2. CSAPP:datalab实验记录

    CSAPP:datalab实验记录 bitXor /* * bitXor - x^y using only ~ and & * Example: bitXor(4, 5) = 1 * Lega ...

  3. CSAPP lab1 datalab-handout(深入了解计算机系统 实验一)

    主要涉及计算机中数的表示法: (1)整数: two's complement,即补码表示法 假设用N位bit表示整数w: 其中最左边一位为符号位,符号位为0,表示正数,为1表示负数. (2)浮点数: ...

  4. CSAPP 之 DataLab 详解

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

  5. CSAPP lab1——位运算

    本次为一次计算机系统实验,就是使用一些基本的运算符来实现函数功能. ps做这些题让我想起大一上学期刚学二进制时被鹏哥支配的痛苦. 知识准备: 1.负数等于正数取反加一. 2.左移一位相当于将这个数扩大 ...

  6. CSAPP实验——DataLab

    任务:按照要求补充13个函数,会限制你能使用的操作及数量 bitXor(x,y) 只使用 ~ 和 & 实现 ^ tmin() 返回最小补码 isTmax(x) 判断是否是补码最大值 allOd ...

  7. CSAPP DataLab

    注意不同版本的题目可能会有所不同,搜了很多他们的题目和现在官网给的实验题都不一样,自己独立思考完整做一遍顺便记录一下. PS:这些难度为1的题有的说实话我都做了挺久的,不过完整做一遍感觉很有意思,这些 ...

  8. CSAPP缓冲区溢出攻击实验(上)

    CSAPP缓冲区溢出攻击实验(上) 下载实验工具.最新的讲义在这. 网上能找到的实验材料有些旧了,有的地方跟最新的handout对不上.只是没有关系,大体上仅仅是程序名(sendstring)或者參数 ...

  9. 6.828 lab1 bootload

    MIT6.828 lab1地址:http://pdos.csail.mit.edu/6.828/2014/labs/lab1/ 第一个练习,主要是让我们熟悉汇编,嗯,没什么好说的. Part 1: P ...

随机推荐

  1. 前端开发利器 Sublime Text 3 使用技巧和总结笔记

    这篇文章是本人在使用该工具进行前端开发的自我总结,思路也许不是很清楚,不过还是希望对读者的你有所帮助,千万别把这边文章收藏起来发霉哦,无论背多少次快捷键,还不及自己多实际操作几次. 目前官方版正式版 ...

  2. 程序兵法:Java String 源码的排序算法(一)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第103篇原创 <程序兵法:Java Str ...

  3. Node.js学习(第四章:初见express)

    Express框架是一款简洁而灵活的node.js web应用框架.前面我们自己手动创建服务器在Express中就是一个API的事情,这就使得我们更加注重业务的功能和开发效率上,不必纠结过多底层的事情 ...

  4. HDU3038【种类并查集】

    题意: 给出m组区间[a,b],以及其区间的和,问有矛盾的有几组: 思路: 种类并查集. 主要是几个关系:同类元素的关系,父亲与儿子的关系,不同类元素的关系: 我们可以类似看作一个前缀和,sum[x] ...

  5. C# 正则表达式输出查询结果

                //正则 第一种方法             Regex regex = new Regex(@"\d{0,}\.\d{0,}\,\d{0,}\.\d{0,}&quo ...

  6. 原来TextBox打开了MultiLine之后就不能使用AutoComplete了

    private void Form1_Load(object sender, EventArgs e) { // Create the list to use as the custom source ...

  7. MyBais中xxMap.xml中的知识点

    添加新的mapper的时候下面两个标红的地方要注意,如果统一约定好命名的话都还好,但是就怕一会这样一会那样的业务代码:总之小心! <!-- spring与mybatis整合配置,扫描所有dao, ...

  8. st表求区间最大值

    Input 第一行给出一个数字N,接下来N+1行,每行给出一个数字Ai,(0<=i<=N<=1E6)接来给出一个数字Q(Q<=7000),代表有Q个询问每组询问格式为a,b即询 ...

  9. go系列(2)- go框架beego以及命令bee的使用

    上篇写了go的安装和GOPATH的配置,linux下go的安装 ,现在就看看如何用框架. 1.进入GOPATH的目录 cd /data/work/go 2.下载beego,通过go get go ge ...

  10. .Net Core应用框架Util介绍(二) 转

    Util的开源地址 https://github.com/dotnetcore/util Util的开源协议 Util以MIT协议开源,这是目前最宽松的开源协议,你不仅可以用于商业项目,还能把Util ...