Bits & Bytes
Everything is bits.
计算机为什么要选择二进制作为基数呢?
因为晶体管的开/关最容易实现和分辨。而其他1/3,1/4…都不好判断,更何况电路还有噪声呢,电路还有不稳定的时候呢。
进制之间的转换:二进制binary 八进制octal 十进制decimal 十六进制hexadecimal
1 Byte=8 bits
16是2的指数,所以可以用4位二进制表示;10不是,所以十进制不能直接与二进制对应转换。
Data Representations:
Boolean Algebra
1.逻辑操作:&& || ! (非0即1)
可以用p && *p来avoids null pointer access
2.按位操作:& | ^ ~ (把变量值看成bit vector)
可以利用bits来Representing & Manipulating Sets
3.移位操作
逻辑移位与算数移位
注意:Shift amount < 0 or >= word size将会导致Undefined Behavior!(C语言不允许,但是高级语言例如Java对此进行了处理)
Integers
整数的二进制编码:
Unsigned/Two’s Complement(2的补,第一位为符号位,sign bit)
一个3bit数,000, 001 ,… , 110, 111
111+1=1000,可是我们没有第四位,所以结果是000。我们知道数学上X+Y=0,则Y=-X,那么此时Y=-111,也就是说在计算机里-111=1?貌似哪里错了。
我们不妨先对这个等式两边+1看看:
111=-1
000=0=000
001=001
010=010
…
貌似又回到正轨上了。
我们再看看一个数加上它的取反变成了什么:
10110
+ 01001
--------------
11111
按照前面的理论也就是-1.而
11111
+ 1
-------------
00000
形成了一个循环。
我们得到X+(~X+1)=0, ==> X=-(~X+1) ==> ~X+1= -X
这样我们就得到了负数的二进制表示。这种方法可以使得正负数都能additive inverse。
在这个补码系统里,我们用最高位表示符号位,以区分正负数。
最大的正数,0111 1111 2^(w-1)-1
按照这个规则,0有两种,1000 0000(-0)和 0000 0000(+0),但是规定-0为最小的负数-2^(w-1),成为一个环。(PS:其实这里理解为规定也有些牵强,可以通过上述方式推理得到,但是我自己从不同方式推得到的结果不同,暂时理解为规定吧)
最小的负数,1000 0000 -2^(w-1)
所以8位signed,可以表示正数0~127,负数-128~-1
2’s Comp. → Unsigned:
顺序反转:Negative → Big Positive
C语言里的signed与unsigned:
1.常数默认为signed:1234;表示unsigned加后缀U:1234U
2.转换:int ty; unsigned uy; uy = (unsigned) ty;
3.如果表达式里既有unsigned又有signed,那么signed将会转换成unsigned计算
Expending,truncating,扩展和截断的一些基本规律:
unsigned:补0;
signed:扩展符号位
这节课主要是二进制的一些东西,还没讲完,下一课会接着讲。