20135223何伟钦—信息安全系统设计基础第三周学习总结

信息的表示和处理

2.0三种数字表示

无符号:编码基于传统的二进制表示法,表示大于或者等于零的数字。

补码:编码是表示有符号整数的最常见的方式,有 符号整数就是可以为正或者为负的数字。

浮点数:编码是表示实数的科学记数法 的以二为基数的版本。

溢出(overflow)的例子:使用 32 位来表示数据类型int,计算表达式200*300*400*500会得出结果 -884 901 888。 这违背了整数运算的特性,计算一组正数的乘积不应产生一个为负的结果。

2.1信息存储

机器级程序将存储器视为一个非常大的字节数组,称为虚拟存储器。存储器的每个字节都由一个唯一的数字来标识,称为它的地址,所有可能地址的集合称为虚拟地址空间。

1.十六进制表示法

十六进制(简写为“hex”)

使用数字 ‘0’~‘9’,以及字符‘A’~‘F’来表示 16 个可能的值。(由于以前多次学习,已基本掌握)

2.字

每台计算机都有一个字长,指明整数和指针数据的标称大小。因为虚拟地址是以这样的一个字来编码的,所以字长决定的最重要的系统参数就是虚拟地址空间的最大大小。对于一个字长为w位的机器而言,虚拟地址的范围为0~2w-1,程序最多访问2w个字节,计算机多为32和64位。

3.数据大小

     C声明

   32位机器

   64位机器

     char

      1

      1

   Short int

      2

      2

      int

      4

      4

    Long int 

      4

      4

     Char *

       4

      8

     float

       4

      4

     double

       8

      8

l 声明指针(T *p;char *p)

4.寻址和字节顺序

小端法——在存储器中按照从最低有效字节到最高有效字节的顺序存储对象。

大端法——从最高有效字节到最低有效字节的顺序存储。

小端法:高对高,低对低。

大端法:高对低,低对高。

强制类型转换(cast):以一种数据类型引用一个对象,而这种数据类型与创建这个对象时定义的数据类型不同。

给C语言初学者:

①使用typedef命名数据类型:改善代码的可读性

②使用printf格式化输出:(同类fprintf和sprintf)打印信息

以'%'开始的字符序列都表示如何格式化下一个参数。 

示例:'%d'是输出一个十进制整数,'%f'是输出一个浮点数,而'%c'是输出一个 字符,其编码由参数给出。

③指针和数组

用数组表示法来引用指针

用指针表示法来引用数组元素。

如:引用 start[i]表示我们想要读取以start指向的位置为起始的第i个位置处的字节。

④指针的创建和间接引用

取地址运算符&

&x创建了一个指向保存变量x的位置的指针

三个指针类型:int*、float*和void**。(数 据类型void*是一种特殊类型的指针,没有相关联的类型信息。) 

强制类型转换运算符可以将一种数据类型转换为另一种。因此,强制类型转换(byte_ pointer)&x表明无论指针&x以前是什么类型,它现在就是一个指向数据类型为unsigned char的指针。这里给出的这些强制类型转换不会改变真实的指针,它们只是告诉编译器以新的 数据类型来看待被指向的数据。

 

5.表示字符串

C 语言中字符串被编码为一个以null字符结尾的字符数组

ASCLL编码:命令man ascii:得到ASCII字符码表

6.表示代码

二进制代码在不同的操作系统上有不同的编码规则。所以二进制代码是不兼容的

7.布尔代数

布尔代数运算(| 就是 OR(或),& 就是 AND(与),~ 就是 NOT(取反), ^  EXCLUSIVE-OR(异或))

① ~ 对应于逻辑运算 NOT:当 P 等于 0 时,~P 等于 1,反之亦 然。 ②& 对应于逻辑运算AND,只有当p =1且q =1时,p & q才等于1。

③|对应于逻辑运算OR,当p =1或者q =1时, p|q等于1

④^ 对应于逻辑运算异或,当p =1且q =0,或者p =0且q =1时,p^q等于1

 

8.C语言中的位级运算

位级运算:将十六进制的参数扩展成二进制表示并执行二进制运算,然后再转换回十六进制。

逻辑:逻辑运算符 “||、&&、!”分别对应于命题逻辑中的OR、AND、NOT运算。

移位:对于无符号数据,右移必须是逻辑的。而对于有符号数据,算术的或者逻辑的右移都可以。

运算:位向量按位进行逻辑运算,结果仍是位向量(区别于逻辑运算)

※常见用法:掩码——用来选择性的屏蔽信号

掩码是一个位模式,表示从一个字中选出的位的集合。

用位向量给集合编码,通过指定掩码来有选择的屏蔽或者不屏蔽一些信号

比如:某一位位置上为1时,表明信号i是有效的;0表示该信号被屏蔽。这个掩码就表示有效信号的集合。

例:0xFF,表示屏蔽除最低有效字节之外的所有字节。

所以任取一个数x=0x934ADFEC,x&0xFF=0x000000EC

~0:生成一个全1的掩码。

9.逻辑运算

逻辑运算符

与:&&

或:|| 

非:! 

计算方法:所有非零参数都代表TRUE,0参数代表FALSE

逻辑运算的结果:1-代表TRUE;0-代表FALSE

逻辑运算和位运算的区别

l 只有当参数被限制为0或1时,逻辑运算才与按位运算有相同的行为。

l 如果对第一个参数求值就能确定表达式的结果,逻辑运算符就不会对后面的参数求值。

10.语言中的移位运算

1.左移<<

 2.右移>>

逻辑右移:在左端补k个0,多用于无符号数移位运算

算术右移:在左端补k个最高有效位的值,多用于有符号数移位运算。

☆注意:Java中用>>表示算术右移,用>>>表示逻辑右移

            移位运算优先级小于算术运算

2.2整数表示

1、整型数据类型

整型数据类型——表示有限范围的整数,每种类型都能用关键字来指定大小,还可以指定是非负数(unsigned)还是负数(默认)。这些不同大小的分配的字数会根据机器的字长和编译器有所不同。

要用ISO C99中的“long long”类型,编译时要用 gcc -std=c99

2、无符号数编码

无符号数的二进制表示的一个重要性质:0-(2^w)-1中的每一个整数和长度为w的位向量是一一对应的

3、补码编码

补码的范围:-2^(w-1)~2^(w-1)-1

在可表示的取值范围内的每个数字都有一个唯一的w位的补码编码

  • 有符号数的其他表示方法:反码、原码

      补码的利用寄存器的长度是固定的特性简化数学运算

 4、有符号数和无符号数之间的转换

强制类型转换:结果保持位值不变,只是改变了解释这些位的方式

函数U2T:从无符号数到补码;T2U:从补码到无符号数

 5.C语言中的有符号数和无符号数

无符号常量:后缀字符U或u

1.转换原则:底层的位保持不变

(1)有符号数→无符号数

非负数——保持不变

负数——转换成大正数

(2)无符号数→有符号数

以2^*(w-1)为界限:

小于它——保持不变

大于它——转换为负数值

[0,2^(w-1))范围内的数字,无符号和补码表示相同;范围之外的,需要加上或者减去2^w

2.运算时若同时存在有符号数和无符号数,会隐式的将有符号数强制类型转换为无符号数,并且假设这两个数都是非负的。

 6、扩展一个数字的位表示

扩展:从一个较小的数据类型转换为较大的数据类型,同时保持数值不变。

1.零扩展:在开头加上0。多用于无符号数转换为一个更大的数据类型。

2.符号扩展:添加最高有效位的副本。多用于补码数字转换

 7、截断数字

截断:减少表示一个数字的位数。而这么做可能会改变它的值,这也是溢出的一种形式。

将一个w位的数截断为k位数字时,就会丢弃高w-k位。

  • 对于无符号数来说,就相当于 mod 2的k次幂
  • 对于有符号数来说,先按照无符号数截断,然后再转化为有符号数

 

2.3 整数运算

1.无符号加法

等价于计算和mod2^w,直接丢弃x+y的w+1位表示的最高位

2.补码加法

本质:模掉w位的补码最高有效位的权重2的w次幂

结果:正溢出、正常、负溢出

  • 两个数的w位补码之和与无符号之和有完全相同的位级表示

 3.补码的非

x=-2^(w-1)时,为-2^(w-1)

x>-2^(w-1)时,为-x

 

  • 补码的位级表示:

对每一位求补,再对结果+1

设k为最右面的1的位置,将k左边的所有位取反

 4.无符号乘法

   计算乘积模2

 5.补码乘法

将2w位的乘积截断为w位。也就是说,需要mod 2的w次幂。

  • 对于无符号和补码乘法来说,乘法运算的位级表示都是一样的

 6.乘以常数

乘法指令很慢,而加法和移位相对较快。所以在编译器中,会使用移位和加法运算组合的方式来代替乘以常数因子

常数为2的k次幂的时候

直接左移k位即可。

常数不是2的整数次幂的时候

将常数C表示为2的几个整数次幂的和,结合移位运算和加法运算。

 

注意:溢出不影响结果

 7.除以2的幂

机器运算中,除法比乘法更慢。当被除数为2的整数次幂时,通过右移来解决。右移时需要区分无符号数和补码。

  • 注意:整数除法总是舍入到零

①无符号数——逻辑右移

无符号数除以2的k次幂,就等同于对其逻辑右移k位。

②补码——算术右移

补码进行算术左移时,需要考虑补码数的正负,因为整数除法总是舍入到零,无符号数中没有负数不必担心,但补码中有正有负,正数向下舍入到零,负数应该向上舍入到零。所以这里涉及到在移位前偏置。
也就是说:

  • x≥0时,除以2的k次幂等价于将x算术右移k位
  • x<0时,先将x加上(2^k)-1,再算术右移k位

 

4.浮点数

浮点表示对形如V=x X (2^y)的有理数进行编码,适用于非常大的数字、非常接近于0的数字或作为实数运算的近似值

不太关注精确;关注速度和简便性

1、二进制小数

将一个数表示为形如x/(2^k):将x的写成为二进制,并将二进制小数点插入从右边算起的第k个位置

 2、IEEE浮点表示

1.IEEE浮点标准:

     用V=(-1)^s*M*2^E来表示一个数:

         符号:s决定这个数是正还是负。0的符号位特殊情况处理。

         阶码:E对浮点数加权,权重是2的E次幂(可能为负数)

   尾数:M是一个二进制小数,范围为1~2-ε或者0~1-ε(ε=1/2的n次幂

2. 编码规则:

单独符号位s编码符号s,占1位

k位的阶码字段exp编码阶码E

n位小数字段frac编码尾数M(同时需要依赖阶码字段的值是否为0)

3.两种精度

单精度(float),k=8位,n=23位,一共32位;

双精度(double),k=11位,n=52位,一共64位。

4.三种编码情况

  • 规格化的值

即exp的位模式既不全0也不全1的时候,这是最一般最普遍的情况,因而是规格化的。

(1)阶码字段和阶码

这里是以偏置形式表示的有符号整数。

阶码E = e-Bias

Bias=[2^(k-1)-1]

(2)小数字段和尾数

二进制小数点在小数字段最高有效位的左边。

尾数M = 1+f(隐含的以1开头的表示)

  • 非规格化的值

即阶码域全为0时的数。

(1)阶码

阶码E = 1-Bias

(2)尾数

尾数M = f(小数字段的值,不包含隐含的1)

(3)非规格化的功能:

a. 提供了一种表示数值0的方法。

b. 表示那些非常接近零的数。逐渐溢出

  • s   特殊值

特殊值是在阶码位全为1的时候出现的。分为两种情况:

(1)无穷:小数字段全为0

(2)NaN不是一个数

小数字段非0

一些运算的结果不能是实数或无穷的时候会返回这样的值。或者表示未初始化的数据。

3.数字示例

看书理解,这里不做详细说明

4.舍入

舍入:找到和数值x最接近的匹配值x',可以用期望的浮点形式表示出来。

①向偶舍入

即:将数字向上或向下舍入,是的结果的最低有效数字为偶数。(四舍六入,五求偶

能用于二进制小数。

②向零舍入

即:把整数向下舍入,负数向上舍入。

③向下舍入

正数和负数都向下舍入。

④向上舍入

正数和负数都向上舍入。

 5.浮点运算

①浮点加法

浮点加法是可交换的

浮点加法不具结合性

大多数值的浮点加法都有逆元,除了无穷和NaN。

浮点加法满足单调性

②浮点乘法

浮点乘法是可交换的

浮点乘法不具有结核性

浮点乘法的单位元为1.0

浮点乘法在加法上不具备分配性

在一定条件下满足单调性

 6.C语言中的浮点数

两种浮点数类型:float和double

int、float、double的相互强制类型转换(int是32位的)

int → float 不会溢出但有可能舍入

int/float → double 结果保留精确数值

double → float 可能溢出为±∞,由于精确度较小也有可能被舍入

float/double → int 向零舍入,可能溢出。

 

学习体会

     在这周的学习中,我学习了用各类方法来表示基本的数据类型,再操作这些数据。在核心部分,我们需要方法来表示基本数据类型,然后考虑到编译器如何将C程序翻译成这样的指令。在接下来学习的几种实现处理的方法,帮助我们更好的了解硬件资源是如何被用来执行的,从而分析最大程序化的性能。

  在了解了这些编译器和机器级代码,在今后的C程序编写时就可以获得最高性能。在掌握了这些技术后我们将会写出安全、可靠的充分利用计算机资源的程序。

posted on 2015-10-04 20:35  20135223  阅读(216)  评论(1编辑  收藏  举报