蓝点工坊(http://www.bluedrum.cn) 创始人,App和嵌入式产品开发。同时也做相应培训和外包工作。 详细介绍 http://pan.baidu.com/s/1y2g88
全部博文(311)
分类: C/C++
2010-05-21 16:40:21
首先某个基本类型占用宽度是确定的.在32 位CPU下,unsigned char /char占一个字节,unsigned int /int 占四个字节,unsigned long /long 也是占用四个字节.
因为数字编码是二进制表示的.(0,1),某一个类型的数就是内存中以二进制来表示.
我们正整数为例,以unsigned char 型的数18为例.
18 (10) =00010010 (2)
在内存即用上述00010010表示
在数值前直接加一符号位的表示法
l [+7]原= 0 0000111 B
l [-7]原= 1 0000111 B
– 0就有两个表达方法
l [+0]原=00000000B [-0]原=10000000B
– 8位二进制原码的表示范围:-127~+127
这种方法直观易懂,又好理解。但是最大问题出在硬件加法器的设计上。为了硬件设计简单,在硬件加法器不管符号位,整体做位运算的。
l 带符号位的原码进行乘除运算时结果正确,而在加减运算的时候就出现了问题 .
– 正确结果
– 1 (10)- 1 (10) = 1 (10) + ( -1 )(10) = 0 (10)
– 用原码运算的结果
– (00000001)原 + (10000001)原 = (10000010)原 = ( -2 ) 显然不正确.
2.2 反码表示法
l 为解决原码的运算错误,人们提出了反码表示法
– 正数:正数的反码与原码相同。
– 负数:负数的反码,符号位为“1”,数值部分按位取反。
– 反码表示例子
l [+7]反= 0 0000111 B
l [-7] 反= 1 1111000 B
– 0也有两种反码表示
l [+0]反=00000000B
l [- 0]反=11111111B
– 8位二进制反码的表示范围:-127~+127
反码表示法的缺点
l 反码运算例子1
– 1(10) - 1(10)= 1(10) + (-1)(10)= ( 0 )(10)
– (00000001) 反+ (11111110)反 = (11111111)反 = ( -0 ) 有问题.
l 反码运算例子2
– 1(10) - 2(10) = 1(10) + ( -2 ) (10) = (-1) (10)
– (00000001) 反+ (11111101)反 = (11111110)反 = ( -1 ) 正确
问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的 .
2。3 补码表示法
l 为了解决上述问题,人们最终采用补码表示法
– 正数:正数的补码和原码相同。
– 负数的补码则是符号位为“1”,数值部分按位取反后再在末位(最低位)加1。也就是“反码+1”。
– 例子
l [+7]补= 0 0000111 B
l [-7]补= 1 1111001 B
– 在补码中用(-128)代替了(-0),所以补码的表示范围为:(-128~0~127)共256个.
l (-128)没有相对应的原码和反码, (-128) = (10000000)
l 已知原码,求补码。
– 问:已知某数X的原码为10110100B,试求X的补码和反码。
– 解:由[X]原=10110100B知,X为负数。求其反码时,符号位不变,数值部分按位求反;求其补码时,再在其反码的末位加1。
– 故:[X]补=11001100B,[X]反=11001011B。
–
l 已知补码,求原码。
– 问:已知某数X的补码11101110B,试求其原码。
– 解:由[X]补=11101110B知,X为负数。求其原码表示时,符号位不变,数值部分按位求反,再在末位加1。
3.1 0取反的值是多少?
printf("%d",~0);
0取反.即全1.是一个负数.将其当成补码,减去1后再取反,得到1.上述打印值是-1
3.2 -1 取反的值是多少?
printf("%d",~(-1));
-1的补码是 全1.取反后是0.因此其取反是输出是0
3.3 问:printf(“%d”,~2)输出?
– ~是表示位取反,%d表示按有符号输出即这个数的每一位都由0变1,1变0,本题问的2取反后,新的有符号数的值是什么?
l 解:2是正数 ,采用原码表示10B,%
1=0001
2=0010
3=0011
4=0100
5=0101
6=0110
7=0111
8=1000
9=1001
Decimal | Binary | BCD | |
---|---|---|---|
Unpacked | Packed | ||
0 | 0000 0000 | 0000 0000 | 0000 0000 |
1 | 0000 0001 | 0000 0001 | 0000 0001 |
2 | 0000 0010 | 0000 0010 | 0000 0010 |
3 | 0000 0011 | 0000 0011 | 0000 0011 |
4 | 0000 0100 | 0000 0100 | 0000 0100 |
5 | 0000 0101 | 0000 0101 | 0000 0101 |
6 | 0000 0110 | 0000 0110 | 0000 0110 |
7 | 0000 0111 | 0000 0111 | 0000 0111 |
8 | 0000 1000 | 0000 1000 | 0000 1000 |
9 | 0000 1001 | 0000 1001 | 0000 1001 |
10 | 0000 1010 | 0000 0001 0000 0000 | 0001 0000 |
11 | 0000 1011 | 0000 0001 0000 0001 | 0001 0001 |
12 | 0000 1100 | 0000 0001 0000 0010 | 0001 0010 |
13 | 0000 1101 | 0000 0001 0000 0011 | 0001 0011 |
14 | 0000 1110 | 0000 0001 0000 0100 | 0001 0100 |
15 | 0000 1111 | 0000 0001 0000 0101 | 0001 0101 |
16 | 0001 0000 | 0000 0001 0000 0110 | 0001 0110 |
17 | 0001 0001 | 0000 0001 0000 0111 | 0001 0111 |
18 | 0001 0010 | 0000 0001 0000 1000 | 0001 1000 |
19 | 0001 0011 | 0000 0001 0000 1001 | 0001 1001 |
20 | 0001 0100 | 0000 0010 0000 0000 | 0010 0000 |