Bits & Ints
Slides & Book Review
Everything is bits
大多数计机算使用8位的块,或者字节(byte),作为最小的可寻址的内存单位,而不是访问内存中单独的位。机器程序级将内存视为一个非常大的字节数组,称为虚拟内存(virtual memory)。内存的每个字节都由一个唯一的数字来标识,称为它的地址(address),所有可能地址的集合就称为虚拟地址空间(virtual address space)。
Encoding Byte Values
基本数据类型所占字节(byte) 数:
C语言中一个指针的值(无论它指向一个整数、一个结构或是某个其他程序对象)都是某个存储块的第一个字节的虚拟地址。
Boolean Algebra
Shift Operations
Encoding Integers
Numeric Ranges
可以发现取值范围是不对称的,负数的范围比正数大1。
Values for Different Word Sizes
Mapping Between Signed & Unsigned
T2U:
U2T:
Relation Between Signed & Unsigned
Casting Surprises
当执行一个运算时,如果它的一个运算数是有符号的而另一个是无符号的,那么C语言隐会式地将有符号参数强制类型转换为无符号数,并假设这两个数都是非负的,来执行这个运算。
Sign Extension
example:
Truncating
Addition
Unsigned Additon
Two's Complement
Multiplication
Unsigned
Signed
Power-of-2 Mutiply with Shift
左移:
右移:
我们希望当右移后结果朝向0舍入。这对unsigned int没有问题。
对非负的sigend也没有问题,但对于负数来首舍入的方向就和我们希望的相悖了。
解决办法就是在负数右移之前,给它加一个bias,即(1<<k)-1。
如果负数的二进制表示的1到k位都是0,则相当于其可以被2^k整除,不会出现wrong rounding的问题。加上bias之后,1到k位都变为1。之后除以2^k,即向右移动k位后,原先的后k位移动至binary point后并丢弃。bias的加入没有影响。
如果1到k位不全是0,则其不能被2^k整除,会出现wrong rounding。加上bias后,会产生进位,相当于给最终移位后的结果加1,从而rounding的问题。
Why SHould I Use Unsigned?
Don't use without understanding implications!
该例中可能产生死循环!
这里要注意sizeof(int)返回值是unsigned!同样例中也可能会产生死循环。
improvements
Machine Words
Word-Oriented Memory Organizaion
每台计算机都有一个字长(word size),指明指针数据的标称大小(nominal size)。因为 虚拟地址是这以样的一个字来编码的,所以字长决定的重要最的系统参数就是虚拟地址空间的最大大小。
Byte Ordering
最低有效字节在最前面的方式,称为小端法(little endian)。最高有效字节在最前面的方式,称为大端法(big endian)
多字节对象都被存储为连续字的节序列,对象的地址为所使用字节中最小的地址。例如,假设一个类型为int的变量x的地址为0x100,也就是说,地址表达式&x的值为0x100。那么,(假设数类据型int为32位表示)x的4个字节将被存储在内存的0x100、0x101、0x102和0x103位置。