信息的表示和处理
信息存储
机器级程序将内存视为一个非常大的字节数组,称为虚拟内存。
内存的每个字节都由 个唯一的数字来标识,称为它的地址。
所有可能地址的合就称为虚拟地址空间。
十六进制:1-9 A-F
二进制与十六进制的转换相当简单,直接二进制前面补0,四个一组,即可开始转换。
字长:每台计算机都有一个字长,指明指针数据的标称大小。我是这样理解的,因为字节的地址是由唯一的数字来标识的,所以字长决定了计算机的虚拟地址空间大小。
一般来说64位机器可以兼容32位机器的程序。
对于一个x位的机器,虚拟地址的范围是0-2的x-1次方,程序最多访问2的x次方字节
那么,既然字节都是由唯一的数字来标识的,那么我们需要使用这个数据的时候应该如何来寻找他呢?我们必须建立两个规则:这个对象的地址是什么,以及在内存中如何排列这些字节。
在几乎所有的机器上,多字节对象都被存储为连续的字节序列,对象的地址为所使用字节中最小的地址。
—最低有效字节在最前面的方式,称为小端法。
最高有效字节在最前面的 式,称为大端法。
安卓和ios只能运行于小端模式。
其实大多是情况下,字节顺序都是不太重要,有以下三种情况例外:
1.当小端法机器产生的数据被发送到大端法机器或者反过来时,接收程序会发现,字里的字节成了反序的。
2.当阅读表示整数数据的字节序列时字节顺序也很重要。这通常发生在检查机器级程序时。
3.当编写规避正常的类型系统的程序时
表示字符串:
C语言中字符串被编码为一个以 null( 其值为 0) 字符结尾的字符数组。
表示代码:
不通机器类型使用不通的且不兼容的指令和编码方式。二进制代码是不兼容的,二进制代码很少能在不同机器和操作系统组合之间移植。
布尔代数简介:
整数表示
c语言支持多种整型数据类型,表示有限范围的整数.
取值范围不是对称的,负数的范围比整数的范围大1 。
无符号数的二进制表示有一个很重要的属性,就是每个介于0~2的w-1次方之间的数都有唯一一个w位的值编码。
最常见的有符号数的计算及表示方法为补码 。在这个定义中,将最高有效位解释为负权。
补码值得注意的点:
1.补码的范围是不对称的
2.最大的无符号数值刚好比补码的最大值的两倍大一点
3.补码并不是表示负数的唯一方式
有符号数和无符号数之间的转换中。
注意:当执行一个运算时,如果它的一个运算数是有符号的而另一个是无符号的,那么C语言会隐式地将有符号参数强制类型转换为无符号数,并假设这两个数都是非负的,来执行这个运算。
在c语言中,要创建一个无符号常量,必须加上后缀字符 'u' 或者 'u',,如果它的一个运算数是有符号的而另一个是无符号的,那么语言会隐式地将有符号参数强制类型转换为无符号数。
无符号数转换为一个更大的数据类型,只要在表示的开头添加0,叫做零扩展
补码数字转换为一个更大的数据类型,在表示中添加最高有效位的值,叫做符号扩展
关于有符号数和无符号数的转换,数字的扩展与截断,经常发生于不同类型,不同位长数字的转换,这些操作一般都是由计算机自动完成的,但是我们最好要知道计算机是如何完成转换的,这对于我们检查BUG是特别有用的。这些内容我们不一定要都记住,但是当发生错误时,我们是要知道从哪里检查。
接下来就是关于整数运算的内容了。本人不再进行深入研究。
整数运算
无符号加法
考虑溢出,C 语言不会将溢出作为错误发出信号:
无符号数求反:
补码加法:
正溢出的结果是负数,负溢出的结果是正数。
补码的非:
无符号乘法
补码乘法
可以认为补码乘法和无符号乘法的位级表示是一样的
乘以常数
大多数机器上,整数乘法需要 10 个或更多的时钟周期,而加法、减法、位级运算和移位只需要 1 个时钟周期。
编译器对整数乘法进行优化的方式:用移位和加法或减法运算的组合来代替常数因子的乘法。
除以 2 的幂
大多数机器上,整数除法更慢,需要 30 个或更多的始终周期。
(只有)除以 2 的幂可以用移位运算来代替,无符号采用逻辑右移,补码采用算术右移
对于有符号数而言,算术右移的结果相当于进行除法运算后向下舍入。
关于整数运算的最后思考
补码使用了与无符号算术运算相同的位级实现,包括加法、减法、乘法甚至除法。都有完全一样或非常类似的位级行为。
浮点数
二进制小数
小数的二进制表示法只能表示那些能够写为 x * 2^w 的数,其他的数都是近似表示。
浮点运算的不精确性可能产生严重后果。
IEEE 浮点表示
在对浮点数的位编码时:
被编码的值分为三种情况:
1.规格化的值:阶码字段即不全为 0 也不全为 1 时属于规格化值(0001~1110)
阶码字段解释方式:E = e - (2^(k-1)-1);如 k=4 时,E 的范围是 -6~7;单精度为 -126~127
小数字段解释方式:M = 1 + f
2.非规格化的值:阶码字段全为 0 时属于非规格化形式
阶码字段解释方式:E = 1 - (2^(k-1)-1);与规格化值中 e = 1 时的 E 相同
小数字段解释方式:M = f
3.特殊值:阶码字段全为 1 时,分两种情况:
小数字段全为 0:表示无穷
小数字段非零:表示 NaN。比如 无穷-无穷 的结果就返回 NaN
舍入
因为表示方法限制了浮点数的范围和精度,所以浮点运算只能近似地表示实数运算。
在浮点数的近似匹配上,IEEE 浮点格式定义了四种舍入方式(默认第一种):
1.向偶数舍入(向最接近的值舍入):非中间值 (0.5) 四舍五入,中间值向偶数舍入。
2.向零舍入
3.向下舍入
4.向上舍入
向偶数舍入可以计算一组数的平均数时避免统计偏差。
实际上这种舍入是发生在二进制小数上的。
总结
计算机将信息编码为位(比特),通常组织成字节序列。有不同的编码方式(无符号、补码、浮点)来表示整数、实数和字符串。
64位字长的机器普及,突破了32位程序4GB虚拟地址空间的限制。(虚拟地址用一个字来编码,所以字长决定了虚拟地址空间的大小)
大多数机器对整数使用补码编码,而对浮点数使用IEEE标准编码,在位级上理解这些编码,并且理解算术运算的数学特性,十分重要。
无符号数和补码的运算都满足整数运算的许多其他属性,包括结合律、交换律和分配律的属性。