CSAPP lab1 datalab-handout_dianshu1593的博客-程序员ITS203

技术标签: c/c++  

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

完整的实验包:链接: 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 >> 16)) << 4;                //如果x >> 16非零,则至少有16位
  5     x = x >> bit_16;
  6     bit_8 = (!!(x >> 8)) << 3;
  7     x = x >> bit_8;
  8     bit_4 = (!!(x >> 4)) << 2;
  9     x = x >> bit_4;
 10     bit_2 = (!!(x >> 2)) << 1;
 11     x = x >> bit_2;
 12     bit_1 = x >> 1;      //还剩两位时,直接判断首位。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 >> 31; 20 int temp = x ^ k;
     //x为正,temp = x;x为负,temp = ~x 21 int isZero = (!!(temp << 31)) >> 31;
     //x = 0或x = -1时,temp = 0,isZero = 0...0;否则isZero = 1...1 22 bit_16 = (!!(temp >> 16)) << 4; 23 temp = temp >> bit_16; 24 bit_8 = (!!(temp << 8)) << 3; 25 temp = temp >> bit_8; 26 bit_4 = (!!(temp << 4)) << 2; 27 temp = temp >> bit_4; 28 bit_2 = (!!(temp << 2)) << 1; 29 temp = temp >> bit_2; 30 bit_1 = temp >> 1; 31 result = bit_16 + bit_8 + bit_4 + bit_2 + bit_1 + 2;
      //真正位数为bit_16 + ... + bit_1 + 1,再加符号位一位 32 return (!isZero) | (result & isZero); 33 } 34 35 /************************************逻辑右移*************************************/ 36 int logicshift(int x, int n) 37 { 38 int temp = ~(1 << 31); 39 temp = ((temp >> n) << 1) + 1; //生成掩码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)) + 1; //要在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 = (1 << n) + (~0); //temp为baising(偏置),1...1(共n个1) 54 return (x + ((x >> 31) & temp)) >> n; //只有负数才要加偏置,所以temp要与符号位相与 55 } 56 57 /****************************** x < y ? ***********************************/ 58 int isLessOrEqual(int x, int y) 59 { 60 int signx = x >> 31; 61 int signy = y >> 31; 62 int signEqual = (!(signx ^ signy) & ((x + (~y)) >> 31));//符号位不同时,做差 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)) >> 31) & 1; 72 // x-y-1<0 <----------x,y不同号------>x为负,y为正,才为正 73 } 74 75 /****************************不用负号得到-x*********************************/ 76 int negate(int x) 77 { 78 return ~x + 1; //按位取反,末位加一 79 } 80 81 /**********************返回最小的补码***************************************/ 82 int tmin(void) 83 { 84 return 1 << 31; 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 << 3)) & 0xff; //是从0开始数的 97 } 98 99 /*********************************计算x中1的数目*********************************/ 100 int bitCount(int x) 101 { 102 int result; 103 int tmpmark1 = 0x55 + (0x55 << 8); //最大0xff 104 int mark1 = tmpmark1 + (tmpmark1 << 16); 105 int tmpmark2 = 0x33 + (0x33 <<8); 106 int mark2 = tmpmark2 + (tmpmark2 << 16); 107 int tmpmark3 = 0x0f + (0x0f << 8); 108 int mark3 = tmpmark3 + (tmpmark3 << 16); 109 int mark4 = 0xff + (0xff << 16); 110 int mark5 = 0xff + (0xff << 8); //以上生成5个掩码 111 112 result = (x & mark1) + ((x >> 1) & mark1); 113 result = (result & mark2) + ((result >> 2) & mark2); //这两个由于进位问题,不能先加再与 114 result = (result + (result >> 4)) & mark3; //分治 115 result = (result + (result >> 8)) & mark4; 116 result = (result + (result >> 16)) & 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 & 3) == 3); //判断frac最后两位是否为11 126 if (exp == 0x7f800000) 127 return uf; 128 else if (exp <= 0x800000) 129 return s | (((uf ^ s) + lsb) >> 1); //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 >> 31; 139 int exp = (uf >> 23) & 0xff; 140 int frac = uf & 0x007fffff; 141 if (exp < 0x7f) return 0; 142 if (exp > 157) return 0x80000000; //Tmax = 2^31 -1 143 144 abs = ((frac >> 23) + 1) << (exp - 127); //模拟 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 == 0) 160 frac = frac << 1; //frac也可用uf代替,因为此时frac = uf 161 else 162 exp = exp + 0x800000; 163 result = (uf & 0x80000000) | exp | frac; 164 return result; 165 }

 

转载于:https://www.cnblogs.com/lfri/p/9097338.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/dianshu1593/article/details/101524128

智能推荐

[安全攻防进阶篇] 五.逆向分析之Win32 API获取及加解密目录文件、OllyDbg逆向其原理_Eastmount的博客-程序员ITS203

这是作者安全攻防进阶篇,希望对您有所帮助。前文作者讲解了条件语句和循环语句源码还原及流程控制逆向方法,这篇文章将分享勒索病毒,通过编写程序实现获取Windows系统目录文件,并对其进行加密和解密的过程;第二部分详细讲解了OllyDbg和在线沙箱的逆向分析过程,第三部分分享恶意软件如何通过宏脚本发送勒索信息或密码至用户邮箱。基础性文章,希望您喜欢~

MySQL-datetime类型的列设置默认值为CURRENT_TIMESTAMP_pfjia的博客-程序员ITS203_current_timestamp

背景解决方案建立数据表时设置默认值使用ALTER TABLE 修改默认值navicat图形界面设置总结参考背景根据《阿里巴巴Java开发手册(正式版)》,数据表中必备三字段:id,gmt_create,gmt_modified.gmt_create和gmt_modified均为datetime类型.但是datetime类型精确到s,对于有些需要精确到ms的...

2021年学习CV和OpenCV的五个最佳网课_EDPJ的博客-程序员ITS203_opencv和cv

本文将分享学习Computer Vision和OpenCV的最佳网课。这些课程适合想学习计算机视觉和Open CV的高级概念的初学者和经验丰富的程序员。它是机器学习和人工智能中最突出领域之一,并已在各种行业中使用,例如物体检测,自动驾驶汽车,机器人技术等等。计算机视觉是机器能够查看、检测、跟踪、分类、分析对象或与过程图像和视频相关的任何任务;OpenCV是一个流行的Python库,它允许您执行诸如图像过滤之类的事情。在本文中,您将学习许多在线课程,这些课程可以帮助您掌握计算机视觉,其中一些课程将向您展示如

windows下安装gulp-sass编译不过去报错的解决方案;_crper的博客-程序员ITS203

系统及开发环境:win10visual studio 2015python 2+墙内用户执行npm install gulp-sass --save-dev 会发起node-sass的下载请求,而请求的路径是github;具体路径: https://github.com/sass/node-sass/releases进行某个版本下载(针对系统) … 而github上的资源基本是放在Amaz

parse_arguments与sys.argv[]的联系_石小秀1995的博客-程序员ITS203

argparse.ArgumentParser()https://blog.csdn.net/Trofish/article/details/73610007位置参数import argparseparser = argparse.ArgumentParser()parser.add_argument(&amp;quot;echo&amp;quot;,help='pls input parameter echo')a...

mapbox使用_还在下雨吗的博客-程序员ITS203_turf transformtranslate

一、实例化化地图https://www.mapbox.com/mapbox-gl-js/example/simple-map/&lt;script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.43.0/mapbox-gl.js'&gt;&lt;/script&gt;&lt;link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.43.0/mapbox-gl.css' rel='style.

随便推点

POJ 1065 木棍问题 贪心算法_LarryNLPIR的博客-程序员ITS203_木棍 算法

<br />算法分析:先对木棍结构体数组按照l排序,消除一个变量的干扰,然后再找w连续上升的子序列。用临时变量temp,遇到更大的作更新,且标记为0,采用贪心策略去找有几个连续上升的子序列<br />#include <iostream>#include <cstdlib>using namespace std;typedef struct stick{ int l; int w;}stick;int cmp(const void *a,const void *b){

linux 7 打开22端口号,CentOS7/Linux永久开放/查看/删除某个指定的 端口号,如80 22..._weixin_39923262的博客-程序员ITS203

1、开启防火墙systemctl start firewalld2、开放指定端口firewall-cmd --zone=public --add-port=80/tcp --permanent命令含义:--zone #作用域--add-port=80/tcp #添加端口,格式为:端口/通讯协议--permanent #永久生效,没有此参数重启后失效3、重启防火墙firewall-cmd --r...

vue向ifarm传值_Vue倔强青铜-入门和组件化通信_weixin_39624716的博客-程序员ITS203

入门作为前端最容易上手的框架,Vue入门其实没啥说的,我放一段清单的代码,大家能看懂就说明能上手了&lt;template&gt; &lt;div id="app"&gt; &lt;h1&gt;{{title}}&lt;/h1&gt; &lt;div&gt; &lt;input type="text" v-model="val"&gt; &lt;butt...

python 递归深度优先搜索与广度优先搜索算法模拟实现_a315612852的博客-程序员ITS203

一、递归原理小案例分析(1)# 概述递归:即一个函数调用了自身,即实现了递归 凡是循环能做到的事,递归一般都能做到!(2)# 写递归的过程1、写出临界条件2、找出这一次和上一次关系3、假设当前函数已经能用,调用自身计算上一次的结果,再求出本次的结果(3)案例分析:求1+2+3+…+n的数和?#概述'''递归:即一个函数调用了自身,即实现了递归凡是...

js封装_chenggil10的博客-程序员ITS203

var sto = { create: function(){ var m_data = new Object(); m_data.init= function(){ var obj = new Object(); obj.ipage = $("#ipage").val(); obj.stat_cd = $("#stat_cd").val(); ob

Android开源项目分类汇总_HD2452的博客-程序员ITS203_安卓手机hostpad原理

https://github.com/Trinea/android-open-project如果你也对开源实现库的实现原理感兴趣,欢迎 Star 和 Fork Android优秀开源项目实现原理解析欢迎加入 QQ 交流群:383537512(入群理由必须填写群简介问题答案)(二群有空位)377723625(一群已满) 63224677(三群已满) 148844489(四群已满) 2

推荐文章

热门文章

相关标签