第二章 信息的表示和处理
C++和C使用相同的数字表示和运算,java使用了全新的一套,用类来表示普通的数字。
8位的块,字节是最小的可寻址的存储器单位。
机器级程序将存储器视为一个非常大的字节数组,称为虚拟存储器。
所有可能地址的集合称为虚拟地址空间。
16进制的数字表示
32位机器限制虚拟地址空间最大位4G。
小端:最低有效字节在最前面的存储方法。
大端:最高有效字节在最前面的方式。——网络序
应用程序强烈不推荐似乎用强制类型转换,但是在系统级编程来说是非常有用,甚至是必须的。
typedef来命名数据类型可以改善代码的可读性。
sizeof运算符来确定对象使用的字节数。方便可移植。
程序仅仅是字节的序列。机器没有关于原始程序的任何信息,除了可能有些用来帮助调试的辅助表以外。
布尔代数和环
使用异或方式的交换在性能上没有任何优势。
使用位运算方便移植,不假定机器的位长。
对于移位运算,移位量应该是0~n-1之间的值,n是机器的字长。
右移有两种:算数右移左端补0;逻辑右移左端补最高有效位的拷贝。C标准没有明确定义应该使用哪种类型的右移。实际上大多数对有符号整数都使用算数右移。
C整数表示使用二进制补码编码方式。但C标准并没有要求要用二进制补码形式来表示有符号整数,实际上都是这么做的。
C库中的<limits.h>定义了一组常量,来限定数据范围INT_MAX,INT_MIN,UINT_MAX。
要创建一个无符号常量,必须加上后缀字符U或者u。
有符号到无符号数的隐式转换导致一些程序错误,而且不易发觉。java就不支持无符号整数。
GCC使用12个字节表示long double(10个字节就够用)
浮点寄存器使用特殊的80位的扩展精度存储浮点数,比存储器中的值所使用的普通32位单精度和64位双精度更准确。
但是使用-O2编译优化,有时使用寄存器和存储器对于相同值也是不一样的,要在编译选项使用 -ffloat-store来调用gcc,
每个浮点计算结果在试用期那都必须从存储到存储器中,再读回来。但是在有时直接计算比较时还是不准确。
另外一种解决方法就是使用long double类型,但是也是有代价的。
必须非常小心地使用浮点运算,因为浮点运算的范围和精度有限,而且浮点运算并不遵循普遍的算数属性,比如结合性。