CSAPP lab1 datalab-handout(深入了解计算机系统 实验一)
主要涉及计算机中数的表示法:
(1)整数: two's complement,即补码表示法
假设用N位bit表示整数w: 其中最左边一位为符号位,符号位为0,表示正数,为1表示负数。
(2)浮点数: 浮点数采用类似科学计数法的方式
以float为例:编码分为三部分:首位为符号位S,然后是8位指数位exp,最后是23位有效数位frac。
即: x = S*M*2^E
例如: -1.10110 × 2^10
其中:
通常 E = exp - bais, 对于float, bais = 2^(8-1)-1 = 127; M = 1 + frac。
浮点数根据exp的不同有不同解码方式
A. 当exp = 0xFF 时,若frac全为0,表示±∞;若frac不全为0,则表示NaN(Not A Num).
B. 当exp = 0x00 时, 为非规格化的,此时exp=0, 但是 E ≠ 0 - bais 而是规定 E = 1 - bais,
另外,M也不是1+frac, 而是 M=frac, 所以当exp=0且frac=0时,表示±0;
C. 当exp≠0xFF,也≠0x00时位规格化的,此时才有E = exp - bais, M = 1 + frac。
需要说明的是:B中这种设计的特点:
第一,可以编码0,第二,在0附近的数是均匀分布的,最后,从非规格数到规格数是平滑过度的。
(例子参考下面 datalab中的 float_twice)
浮点数的舍入
浮点数的frac部分长度有限,因此精度就有限,比如float精度最大为23位,
若有超过这个精度的数转换为float数,就存在舍入的问题。 一般浮点数舍入遵循两点:
就近舍入(round-to-nearest)和向偶数舍入(round-to-even).
(例子参考下面 datalab中的 float_i2f)
另外给出一个例子:
- int main(int argc, char *argv[]){
- double dt = 0x0.0000008p+;
- double d0 = 0x1.0000010p+;
- for (int i = ; i < ; ++i) {
- printf("=======\n");
- printf("double: %a \n", d0);
- printf("float: %a \n", (float)d0);
- d0 += dt;
- }
- }
结果:
- =======
- double: 0x1.000001p+
- float: 0x1p+
- =======
- double: 0x1.0000018p+
- float: 0x1.000002p+
- =======
- double: 0x1.000002p+
- float: 0x1.000002p+
- =======
- double: 0x1.0000028p+
- float: 0x1.000002p+
- =======
- double: 0x1.000003p+
- float: 0x1.000004p+
- =======
- double: 0x1.0000038p+
- float: 0x1.000004p+
解释略去。
data lab
- /*
- * CS:APP Data Lab
- *
- * <Please put your name and userid here>
- *
- * bits.c - Source file with your solutions to the Lab.
- * This is the file you will hand in to your instructor.
- *
- * WARNING: Do not include the <stdio.h> header; it confuses the dlc
- * compiler. You can still use printf for debugging without including
- * <stdio.h>, although you might get a compiler warning. In general,
- * it's not good practice to ignore compiler warnings, but in this
- * case it's OK.
- */
- #if 0
- /*
- * Instructions to Students:
- *
- * STEP 1: Read the following instructions carefully.
- */
- You will provide your solution to the Data Lab by
- editing the collection of functions in this source file.
- INTEGER CODING RULES:
- Replace the "return" statement in each function with one
- or more lines of C code that implements the function. Your code
- must conform to the following style:
- int Funct(arg1, arg2, ...) {
- /* brief description of how your implementation works */
- int var1 = Expr1;
- ...
- int varM = ExprM;
- varJ = ExprJ;
- ...
- varN = ExprN;
- return ExprR;
- }
- Each "Expr" is an expression using ONLY the following:
- . Integer constants through (0xFF), inclusive. You are
- not allowed to use big constants such as 0xffffffff.
- . Function arguments and local variables (no global variables).
- . Unary integer operations ! ~
- . Binary integer operations & ^ | + << >>
- Some of the problems restrict the set of allowed operators even further.
- Each "Expr" may consist of multiple operators. You are not restricted to
- one operator per line.
- You are expressly forbidden to:
- . Use any control constructs such as if, do, while, for, switch, etc.
- . Define or use any macros.
- . Define any additional functions in this file.
- . Call any functions.
- . Use any other operations, such as &&, ||, -, or ?:
- . Use any form of casting.
- . Use any data type other than int. This implies that you
- cannot use arrays, structs, or unions.
- You may assume that your machine:
- . Uses 2s complement, -bit representations of integers.
- . Performs right shifts arithmetically.
- . Has unpredictable behavior when shifting an integer by more
- than the word size.
- EXAMPLES OF ACCEPTABLE CODING STYLE:
- /*
- * pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
- */
- int pow2plus1(int x) {
- /* exploit ability of shifts to compute powers of 2 */
- return ( << x) + ;
- }
- /*
- * pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
- */
- int pow2plus4(int x) {
- /* exploit ability of shifts to compute powers of 2 */
- int result = ( << x);
- result += ;
- return result;
- }
- FLOATING POINT CODING RULES
- For the problems that require you to implent floating-point operations,
- the coding rules are less strict. You are allowed to use looping and
- conditional control. You are allowed to use both ints and unsigneds.
- You can use arbitrary integer and unsigned constants.
- You are expressly forbidden to:
- . Define or use any macros.
- . Define any additional functions in this file.
- . Call any functions.
- . Use any form of casting.
- . Use any data type other than int or unsigned. This means that you
- cannot use arrays, structs, or unions.
- . Use any floating point data types, operations, or constants.
- NOTES:
- . Use the dlc (data lab checker) compiler (described in the handout) to
- check the legality of your solutions.
- . Each function has a maximum number of operators (! ~ & ^ | + << >>)
- that you are allowed to use for your implementation of the function.
- The max operator count is checked by dlc. Note that '=' is not
- counted; you may use as many of these as you want without penalty.
- . Use the btest test harness to check your functions for correctness.
- . Use the BDD checker to formally verify your functions
- . The maximum number of ops for each function is given in the
- header comment for each function. If there are any inconsistencies
- between the maximum ops in the writeup and in this file, consider
- this file the authoritative source.
- /*
- * STEP 2: Modify the following functions according the coding rules.
- *
- * IMPORTANT. TO AVOID GRADING SURPRISES:
- * 1. Use the dlc compiler to check that your solutions conform
- * to the coding rules.
- * 2. Use the BDD checker to formally verify that your solutions produce
- * the correct answers.
- */
- #endif
- /*
- * bitAnd - x&y using only ~ and |
- * Example: bitAnd(6, 5) = 4
- * Legal ops: ~ |
- * Max ops: 8
- * Rating: 1
- */
- int bitAnd(int x, int y) {
- return ~((~x) | (~y));
- }
- /*
- * getByte - Extract byte n from word x
- * Bytes numbered from 0 (LSB) to 3 (MSB)
- * Examples: getByte(0x12345678,1) = 0x56
- * Legal ops: ! ~ & ^ | + << >>
- * Max ops: 6
- * Rating: 2
- */
- int getByte(int x, int n) {
- int y = x >> (n << );
- return y & 0xFF;
- }
- /*
- * logicalShift - shift x to the right by n, using a logical shift
- * Can assume that 0 <= n <= 31
- * Examples: logicalShift(0x87654321,4) = 0x08765432
- * Legal ops: ! ~ & ^ | + << >>
- * Max ops: 20
- * Rating: 3
- */
- int logicalShift(int x, int n) {
- int y = x >> n;
- int helper = ( << ) >> n;
- helper = ~(helper << );
- return y & helper;
- }
- /*
- * bitCount - returns count of number of 1's in word
- * Examples: bitCount(5) = 2, bitCount(7) = 3
- * Legal ops: ! ~ & ^ | + << >>
- * Max ops: 40
- * Rating: 4
- */
- int bitCount(int x) {
- int mk1, mk2, mk3, mk4, mk5, result;
- mk5 = 0xff | (0xff << );
- mk4 = 0xff | (0xff << );
- mk3 = 0x0f | (0x0f << );
- mk3 = mk3 | (mk3 << );
- mk2 = 0x33 | (0x33 << );
- mk2 = mk2 | (mk2 << );
- mk1 = 0x55 | (0x55 << );
- mk1 = mk1 | (mk1 << );
- // 先把16个相邻两位有几个1,并用这两位表示,然后以此类推,
- // 即: 32->16, 16->8, 8->4, 4->2, 2->1
- result = (mk1 & x) + (mk1 & (x >> ));
- result = (mk2 & result) + (mk2 & (result >> ));
- result = mk3 & (result + (result >> ));
- result = mk4 & (result + (result >> ));
- result = mk5 & (result + (result >> ));
- return result;
- }
- /*
- * bang - Compute !x without using !
- * Examples: bang(3) = 0, bang(0) = 1
- * Legal ops: ~ & ^ | + << >>
- * Max ops: 12
- * Rating: 4
- */
- int bang(int x) {
- return ((x | (~x + )) >> ) + ;
- }
- /*
- * tmin - return minimum two's complement integer
- * Legal ops: ! ~ & ^ | + << >>
- * Max ops: 4
- * Rating: 1
- */
- int tmin(void) {
- return << ;
- }
- /*
- * fitsBits - return 1 if x can be represented as an
- * n-bit, two's complement integer.
- * 1 <= n <= 32
- * Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
- * Legal ops: ! ~ & ^ | + << >>
- * Max ops: 15
- * Rating: 2
- */
- int fitsBits(int x, int n) {
- /*
- n 能表示的数,除去符号位,剩下n-1位,对应到32位int数中:
- 正数应该是前32-(n-1)位都是0,负数应该是32-(n-1)位都是1。
- */
- int signX = x >> ;
- int y = x >> (n + (~));
- return !(signX ^ y);
- }
- /*
- * divpwr2 - Compute x/(2^n), for 0 <= n <= 30
- * Round toward zero
- * Examples: divpwr2(15,1) = 7, divpwr2(-33,4) = -2
- * Legal ops: ! ~ & ^ | + << >>
- * Max ops: 15
- * Rating: 2
- */
- int divpwr2(int x, int n) {
- int signX = x >> ;
- int bias = ( << n) + (~);
- bias = signX & bias;
- return (x + bias) >> n;
- }
- /*
- * negate - return -x
- * Example: negate(1) = -1.
- * Legal ops: ! ~ & ^ | + << >>
- * Max ops: 5
- * Rating: 2
- */
- int negate(int x) {
- return (~x) + ;
- }
- /*
- * isPositive - return 1 if x > 0, return 0 otherwise
- * Example: isPositive(-1) = 0.
- * Legal ops: ! ~ & ^ | + << >>
- * Max ops: 8
- * Rating: 3
- */
- int isPositive(int x) {
- return !((x >> ) | (!x));
- }
- /*
- * 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 signX = x >> ;
- int signY = y >> ;
- int signSame = !(signX ^ signY);
- int diff = x + (~y) + ;
- int diffNegZero = (diff >> ) | (!diff);
- return (signSame & diffNegZero) | ((!signSame) & signX);
- }
- /*
- * ilog2 - return floor(log base 2 of x), where x > 0
- * Example: ilog2(16) = 4
- * Legal ops: ! ~ & ^ | + << >>
- * Max ops: 90
- * Rating: 4
- */
- int ilog2(int x) {
- int bn = (!!(x >> )) << ;
- bn = bn + ((!!(x >> (bn + ))) << );
- bn = bn + ((!!(x >> (bn + ))) << );
- bn = bn + ((!!(x >> (bn + ))) << );
- bn = bn + (!!(x >> (bn + )));
- return bn;
- }
- /*
- * float_neg - Return bit-level equivalent of expression -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 representations of
- * single-precision floating point values.
- * When argument is NaN, return argument.
- * Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
- * Max ops: 10
- * Rating: 2
- */
- unsigned float_neg(unsigned uf) {
- /*
- * s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
- * s is sign bit, when xs are all ZERO, this represents inf,
- * and when xs are not all ZERO, it's NaN.
- */
- unsigned fracMask, expMask;
- unsigned fracPart, expPart;
- fracMask = ( << ) - ;
- expMask = 0xff << ;
- fracPart = uf & fracMask;
- expPart = uf & expMask;
- if ((expMask == expPart) && fracPart) {
- return uf;
- }
- return ( << ) + uf;
- }
- /*
- * float_i2f - Return bit-level equivalent of expression (float) x
- * Result is returned as unsigned int, but
- * it is to be interpreted as the bit-level representation of a
- * single-precision floating point values.
- * Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
- * Max ops: 30https://www.linuxmint.com/start/sarah/
- * Rating: 4
- */
- unsigned float_i2f(int x) {
- unsigned signX, expPart, fracPart;
- unsigned absX;
- unsigned hp = << ;
- unsigned shiftLeft = ;
- unsigned roundTail;
- unsigned result;
- if ( == x) {
- return ;
- }
- absX = x;
- signX = ;
- if (x < ) {
- absX = -x;
- signX = hp;
- }
- while ( == (hp & absX)) {
- absX = absX << ;
- shiftLeft += ;
- }
- expPart = + - shiftLeft;
- roundTail = absX & 0xff;
- fracPart = (~(hp >> )) & (absX >> );
- result = signX | (expPart << ) | fracPart;
- // 离大数更近时,进位;离小数更近时,舍位。
- if (roundTail > 0x80) {
- result += ;
- } else if (0x80 == roundTail) {
- // 离两边同样近时,根据左边一位舍入到偶数,左边一位为1则进,为0则舍。
- if (fracPart & ) {
- result += ;
- }
- }
- return result;
- }
- /*
- * float_twice - 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 float_twice(unsigned uf) {
- unsigned signX, expPart, fracPart;
- unsigned helper = << ;
- unsigned fracMask = ( << ) - ;
- if ( == uf) { // positive 0
- return ;
- }
- if (helper == uf) { // negative 0
- return helper;
- }
- signX = uf & helper;
- expPart = (uf >> ) & 0xff;
- if (expPart == 0xff) {
- return uf;
- }
- fracPart = uf & fracMask;
- if ( == expPart) { // 非规格化值
- fracPart = fracPart << ;
- if (fracPart & ( << )) {
- fracPart = fracPart & fracMask;
- expPart += ;
- }
- } else {
- expPart += ;
- }
- return signX | (expPart << ) | fracPart;
- }
CSAPP lab1 datalab-handout(深入了解计算机系统 实验一)的更多相关文章
- CSAPP:Lab1 -DataLab 超详解
写在前面 之前考研的时候csapp的书有刷过5,6遍,所以对书本知识还算比较了解.恰逢最近在学c++的时候,顺带刷一下大名鼎鼎的csapp实验. 0. 环境准备 最好准备一个纯净的Linux系统这里建 ...
- CSAPP:datalab实验记录
CSAPP:datalab实验记录 bitXor /* * bitXor - x^y using only ~ and & * Example: bitXor(4, 5) = 1 * Lega ...
- 哈工大 计算机系统 实验二 Datalab数据表示
所有实验文件可见github 计算机系统实验整理 由于word文件没有保存,因此如需参考此实验,请直接访问github文件
- 哈工大 计算机系统 实验七 TinyShell
所有实验文件可见github 计算机系统实验整理 实验报告 实 验(七) 题 目 TinyShell 微壳 计算机科学与技术学院 目 录 第1章 实验基本信息 - 4 - 1.1 实验目的 - 4 - ...
- CSAPP lab1——位运算
本次为一次计算机系统实验,就是使用一些基本的运算符来实现函数功能. ps做这些题让我想起大一上学期刚学二进制时被鹏哥支配的痛苦. 知识准备: 1.负数等于正数取反加一. 2.左移一位相当于将这个数扩大 ...
- CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom
CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom 栈结构镇楼 这里先给 ...
- CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz
前言 完成这个实验大概花费一天半的时间,看了很多大佬的博客,也踩了很多的坑,于是打算写一篇博客重新梳理一下思路和过程,大概会有两篇博客吧. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上 ...
- 哈工大 计算机系统 实验一 Linux下C工具应用
所有实验文件可见github 计算机系统实验整理 实验报告 实 验(一) 题 目 Linux下C工具应用 专 业 计算机学院 学 号 班 级 学 生 指 导 教 师 实 验 地 点 实 验 日 期 计 ...
- CSAPP 之 DataLab 详解
前言 本篇博客将会剖析 CSAPP - DataLab 各个习题的解题过程,加深对 int.unsigned.float 这几种数据类型的计算机表示方式的理解. DataLab 中包含下表所示的 12 ...
随机推荐
- 【图论-最短路】【P3393】逃离僵尸岛
传送门 Description 小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家. 该国有N个城市,城市之间有道路相连.一共有M条双向道路.保证没有自环和重边. K个城市已经被僵 ...
- 如何用好 github 中的 watch、star、fork
http://www.jianshu.com/p/6c366b53ea41 https://www.zhihu.com/question/20431718 在每个 github 项目的右上角,都有三个 ...
- hdu 1754 线段树 单点更新 动态区间最大值
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- rand、randi和randn的区别?
1,rand 生成均匀分布的伪随机数.分布在(0~1)之间 主要语法:rand(m,n)生成m行n列的均匀分布的伪随机数 rand(m,n,'double')生成指定精度的均匀分布的伪随机数,参数还可 ...
- JS如何判断是不是iphoneX
function isIphoneX(){ return /iphone/gi.test(navigator.userAgent) && (screen.height == 812 & ...
- Nginx简介及使用Nginx实现负载均衡的原理【通俗易懂,言简意赅】【转】
Nginx 这个轻量级.高性能的 web server 主要可以干两件事情: 直接作为http server(代替apache,对PHP需要FastCGI处理器支持): 另外一个功能就是作为反向代理服 ...
- 51Nod 1002 数塔取数问题
Input示例 4 5 8 4 3 6 9 7 2 9 5 Output示例 28 DP: 递推式: dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+arr[i][j]; ...
- MSSQL Get Last Monday and Last Sunday
获取上周的周一和周日 代码: --start of last week , ) --end of last week , )
- 知问前端——Ajax提交表单
本文,运用两大表单插件,完成数据表新增的工作. 一.创建数据库 创建一个数据库,名称为:zhiwen,表——user表,字段依次为:id.name.pass.email.sex.birthday.da ...
- Item 3 ------单例模式的几种实现方式,及优缺点
单例模式,是指一个类只有一个唯一的实例,一个类只会被实例化一次.实现这种效果,最佳的方式,编写包含单个元素的枚举类型. 单例模式的最佳实现方式-----创建一个包含单个元素的枚举类 public en ...