无符号:基于传统的二进制表示法,大于等于0
补码:有符号整数
浮点数:实数的科学计数法的以二进制为基数的版本
计算机的表示法是用有限数量的位来对应一个数字编码,当结果太大不能表示时就会发生溢出。人为的溢出是有一定企图的,攻击者写一个超过缓冲区长度的字符串,植入到缓冲区这时可能会出现两种结果:一是过长的字符串覆盖了相邻的存储单元,引起程序运行失败,严重的可导致系统崩溃;另一个结果就是利用这种漏洞可以执行任意指令,甚至可以取得系统root特级权限。
2.1
对于跨越多字节的程序对象,必须建立两个规则:
对象的地址是什么
在存储器中这些字节如何排列
多字节对象被存储为连续的字节序列,对象的地址为所使用字节中最小的地址
大端法&小端法:最低有效字节在最前面的方式称为小端法,最高有效字节在最前面的方式称为大端法。字节顺序是网络编程的基础,小端是“高对高、低对低”,大端与之相反。
字节顺序可见的三种情况:
网络应用程序代码编写时必须遵循已建立的关于字节顺序的规则
反汇编器显示(确定可执行文件所表示的指令序列的工具)
编写规避正常的类型系统的程序时,可以使用强制类型转换来允许一种数据类型引用一个对象
布尔代数
用0、1表示真假,以研究逻辑推理的基本原则。
有:~=NOT;&=AND;|=OR;^=异或
C语言中的位级运算:C语言支持按位的布尔运算。与或非,异或同或常见用法就是实现掩码运算。
C语言中的逻辑运算:逻辑运算符&& 和 || 与它们对应的位级运算& 和 | 之间第二个重要的区别是,如果对第一个
C语言中的移位运算:C 语言标准并没有明确定义应该使用哪种类型的右移
2.2
C语言支持多种整形数据类型——表示有限范围的整数。
要用C99中的“long long”类型,编译是要用 gcc -std=c99
补码编码:最高位有效位也称符号位,权重为-2^w-1。符号位为1是负为0是正。
补码的范围不对称,是因为:一半的数的整数一半是负数,而0是非负
数。最大的无符号数值刚好比补码的最大值的两倍大一点。
有符号数还有两种标准的表示方法:
反码:除了最高有效位的权是-(2w-1-1)而不是-2w-1,它和补码是一样的。
原码:最高有效位是符号位,用来确定剩下的位应该取负权还是正权。
C语言允许在各种不同的数字数据类型之间做强制类型转换。将负数转换成无符号数可能会得到0。如果转换的无符号数太大以至于超出了补码能够表示的范围,可能会得到TMax。
C语言允许有符号数与无符号数之间的转换,转换的原则是底层的位表示保持不变
2.3
1.无符号加法:无符号加法等价于计算和模上2w。可以通过简单的丢弃x + y的w + 1位表示的最高位,来计算这个数值。可以被视为模运算形式,等价于计算和模2^w。
溢出:完整的整数结果不能放到数据类型的字长限制中去
2.补码加法:负溢出得到的结果比整数和大16,正溢出得到的结果比整数小16.
3.补码的非
4.无符号乘法计算公式。
5.补码乘法:给定长度的两个为位向量,无符号乘积的位级与补码乘积的位级表示是相同的,这表明机器可以用一种乘法指令来进行有符号数和无符号数的乘法。
6.乘以常数:为了缩短计算时间,许多C语言编译器试着用移位,加法和减法运算的组合来代替乘以常数的乘法。
7.除以2的幂:除以2的幂可以通过逻辑或者算术右移来实现。
8.关于整数运算的最后的思考:计算机执行“整数”运算实际是一种模运算形式。表示数字的有限字长限制了可能的取值范围,结果可能溢出。补码提供了技能表示正数也能表示负数的灵活方法,同时使用了与执行无符号算数相同的位级实现。
2.4
IEEE浮点标准用V = (-1)^s × M × 2^E的形式来表示一个数:
将浮点数的位表示划分为三个字段,分别对这些值进行编码:
IEEE标准指定了一个简单的规则,用来确定诸如加法和乘法这样的算术运算的结果。把浮点值x和y看成实数,而某个运算⊙定义在实数上,计算将产生Round (x ⊙ y),这是对实际运算的精确结果进行舍入后的结果。当参数中有一个是特殊值(如-0、-∞或NaN)时,IEEE标准定义了一些使之更合理的规则。例如,定义1/-0将产生-∞,而定义1/+0会产生+∞。