整数的表示
整数在C语言中有三种表示方法,分别为signed decimal (24), unsigned hexadecimal ( 0x3C), signed octal (052);
当然int型也可以分成signed和unsigned,无符号整数的取值范围为0..2^32-1, 有符号的取值范围为-2^31 .. 2^31-1.
但是有一个问题是如果所有数据在计算机中以二进制来表示,那在二进制中是怎么表示负数的呢?
所以在整数的编码中,引入了三种编码方式,分别是signed magnitude, ones complement 和 two complement.
Signed magnitude:
即最左边为符号位,0表示正数,1表示负数。例如我们以一个8-bit int 为例子,00000011 为3 , 10000011为-3,但是这就引发了一个问题,我们知道3 + (-3)的结果应该是0,但00000011+ 10000011 = 10000110 不等于0. 如果要弥补这种编码的不足则需要硬件方面的工作了。
ones complement:
为了弥补正负数相加不等于0的问题,one complement出现了。
它的规定是整数的one complement就是signed magnitude的编码,负数的one complement最高位为符号位,其它位是它所对应的signed magnitude 除了符号为以外全部取反。例如我们继续上面的例子,3的one complement为他的signed mag的编码即:00000011, -3则需要将原有的sign magnitude(10000011)除符号位取反,则为11111100,3+(-3) = 00000011 + 11111100 = 11111111 = -0,因为0不分正负,所以结果为0,但-0显然不符合数学习惯,所以twos complement出现了。
twos complement
正数的twos complement和他的signed magnitude一样,负数的则为其one complement + 1;
3的twos complement为00000011, -3为one complement (1111100) + 1 = 11111101; 则3+(-3)= 00000000 = 0;
因为计算机中有符号数用twos complement 表示。
二进制,十进制, 八进制, 十六进制之间的转换:
二进制->十进制:相应位乘相应2的次方。
00001010 = 0*2^7+0*2^6+0*2^5+0*2^5+ 0*2^4+1*2^3+0*2^2+1*2^1+0*2^0= 10
二进制->八进制: 从右到左,每三位二进制数等于一位八进制数。
101010111 = 101 010 111
= 5 2 7
= 0527
二进制->十六进制: 从右到左,每四位二进制数等于一位十六进制数。
10101001101010 = 10 1010 0110 1010
= 2 A 6 A
= 0x2A6A
十进制->二进制:除2取余
789=1100010101(B)
十进制->八进制:同上,除八取余法
十六进制->二进制 : 每一位十六进制数字换成四位二进制;
0x3A9C = 3 A 9 C
0011 1010 1001 1100