主要涉及计算机中数的表示法:

(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(深入了解计算机系统 实验一)的更多相关文章

  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. 哈工大 计算机系统 实验二 Datalab数据表示

    所有实验文件可见github 计算机系统实验整理 由于word文件没有保存,因此如需参考此实验,请直接访问github文件

  4. 哈工大 计算机系统 实验七 TinyShell

    所有实验文件可见github 计算机系统实验整理 实验报告 实 验(七) 题 目 TinyShell 微壳 计算机科学与技术学院 目 录 第1章 实验基本信息 - 4 - 1.1 实验目的 - 4 - ...

  5. CSAPP lab1——位运算

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

  6. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom

    CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom 栈结构镇楼 这里先给 ...

  7. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz

    前言 完成这个实验大概花费一天半的时间,看了很多大佬的博客,也踩了很多的坑,于是打算写一篇博客重新梳理一下思路和过程,大概会有两篇博客吧. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上 ...

  8. 哈工大 计算机系统 实验一 Linux下C工具应用

    所有实验文件可见github 计算机系统实验整理 实验报告 实 验(一) 题 目 Linux下C工具应用 专 业 计算机学院 学 号 班 级 学 生 指 导 教 师 实 验 地 点 实 验 日 期 计 ...

  9. CSAPP 之 DataLab 详解

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

随机推荐

  1. bzoj3157: 国王奇遇记

    emmm...... 直接看题解好了: BZOJ-3157. 国王奇遇记 – Miskcoo's Space O(m)不懂扔掉 总之,给我们另一个处理复杂求和的方法: 找到函数之间的递推公式! 这里用 ...

  2. angularJS 条件查询 品优购条件查询品牌(条件查询和列表展示公用方法解决思路 及 post请求混合参数提交方式)

    Brand.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> &l ...

  3. SQLite 学习笔记

    SQLite 学习笔记. 一.SQLite 安装    访问http://www.sqlite.org/download.html下载对应的文件.    1.在 Windows 上安装 SQLite. ...

  4. TP-LINK TL-WN725N V2 / rtl8188eu Linux驱动安装

    https://github.com/lwfinger/rtl8188eu 驱动下载地址 安装: make all make install 参考一下把 http://devillived.net/f ...

  5. ARM汇编程序闪烁灯与其反汇编代码比较

    /* *LED闪烁 *led.s */ #define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 .global _start //把 _start ...

  6. ps命令查看进程指定项目信息、用户名过长显示UID

    有次一个在使用ps命令时,发现部分用户显示的是用户名,有些用户显示的是UID,那是因为用户名长度超过8位的:也就是说ps命令用户名列默认只能显示8位(含8位)的用户名,超过8位就显示UID,如何让长度 ...

  7. SpringMVC 用注解Annotation驱动的IoC功能@Autowired @Component

    转载自:http://blog.csdn.net/lufeng20/article/details/7598564 本文分为三个部分:概述.使用注解进行属性注入.使用注解进行Bean的自动定义. 一, ...

  8. js和jq实现全选反选

    在前端中用到全选反选的案例并不少,在这里呢我就实现这个功能给大家参考参考. 这里呢就先贴上我的html和css代码 <div class="wrap"> <tab ...

  9. MyBatis框架的使用及源码分析(十) CacheExecutor,SimpleExecutor,BatchExecutor ,ReuseExecutor

    Executor分成两大类,一类是CacheExecutor,另一类是普通Executor. 普通类又分为: ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情.它为每个语句的执行 ...

  10. IConfigurationSectionHandler 接口

    IConfigurationSectionHandler 处理对特定的配置节的访问. 示例代码: public class MyConfig : IConfigurationSectionHandle ...