1.1 无符号二进制整数
计算机是电子电荷集合的方式在内存中宝保存指令和数据,二进制数用两个数字作基础,其中每一个二进制数成为bit
不是0
就是1
.位自右向左,从0开始顺序增加,左边的位称为最高有效位(Most Significant Bit MSB),右边的称为最低有效位(LSB least significant Bit).一个16位的二进制数 其MSB和LSB如下所示:
MSB LSB
1 0 1 1 0 0 1 0 1 0 0 1 1 1 0 0
15 0 位序号
二进制数可以是有符号,也可以是无符号!有符号整数又分为正整数和负数! 无符号整数默认为正数,零也被看作是正数.
1.1.1 无符号二进制数
从LSB
开始,无符号二进制数中的每一个为代表是2的加一次幂.下面的是对一各8位的二进制数来说,2的幂是如何从左到右递增的:
1 1 1 1 1 1 1 1
2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
- 下表列出2^0到2^15的十进制值
2^n | 十进制 | 2^n | 十进制 |
---|---|---|---|
2^0 | 1 | 2^8 | 256 |
2^1 | 2 | 2^9 | 512 |
2^2 | 4 | 2^10 | 1024 |
2^3 | 8 | 2^11 | 2048 |
2^4 | 16 | 2^12 | 4096 |
2^5 | 32 | 2^13 | 8192 |
2^6 | 64 | 2^14 | 16384 |
2^7 | 128 | 2^15 | 32768 |
1.1.2 无符号二进制到十进制的转换
对于一个包含n个数字的无符号二进制数来说,加权位计数法(weighted positionnal notation)提供了一种简便的方法计算十进制值:
D
表示一个二进制数字.比如,二进制数0000 1001
就等于9.如何计算改值呢?首先剔除数字等于0的位(1*2³) (1*2°)=9
计算方式如下:
0 0 0 0 1 0 0 1
| |
1*2³ 1*2° = 9
1.1.3 无符号十进制到二进制的转换
将无符号十进制整数转换为 二进制,方法是不断的将这个整数除以2,并将每个余数记录为一个二进制数字.下表展示的是十进制数37转换为二进制的步骤.
除法 | 商 | 余数 | 除法 | 商 | 余数 |
---|---|---|---|---|---|
37/2 | 18 | 1 | 4/2 | 2 | 0 |
18/2 | 9 | 0 | 2/2 | 1 | 0 |
9/2 | 4 | 1 | 1/2 | 0 | 1 |
将表中的二进制位反序链接起来就得到这个数的二进制数值100101
,由于计算机总是按照8的倍数来组织二进制数字.所以需要在这个数的二进制数的左边加上两个零0010 0101
.
如何计算一各数的二进制数有几位呢?
设无符号十进制数位n
,其对应的二进制数的位数是b
.用对数计算公式就能算出b:
的上限.
例如:如果n=37
则
,取这个结果的上限最小整数5 1
就是这个数转换成二进制后的位数.这个计算公式可以用于任何进制计算位数!
1.1.4 二进制加法
两个二进制整数相加时,是位对位处理的.从最低的一位(右边)开始,依序将每位进行加法运算.两个二进制数相加有四种结果,如下所示:
进制 | 结果 |
---|---|
0 0=0 | 0 1=1 |
1 0=1 | 1 1=10 |
1
与1
相加的结果是二进制的10
(也就是十进制的2).多出来的数值可以向更高位产生一个进位.
- 如下计算方法所示,两个二进制数
0000 0100
和0000 0111
相加
0 0 0 0 0 1 0 0 (4)
0 0 0 0 0 1 1 1 (7)
-------------------------
0 0 0 0 1 0 1 1
7 6 5 4 3 2 1 0 位的序号
从两个数的最低位(位0)开始计算0 1
,得到结果行对应位上的1
,然后计算次低位(位1).在位2上计算1 1
,结果是0
并且向高位产生了一个进位1
.然后计算(位3)0 1
还要加上(位2)的进位,结果就是1
.其余位都是0
.
1.1.5 整数存储大小
在x86
计算机中,所有的数据存储的基本单位是字节byte
.一个字节有8位,其他的存储单位还有字(word 2个字节), 双字(doubleword 4个字节), 四字(quadword 8个字节)
下表列出无符号整数可能的取值范围
代码语言:javascript复制byte --------8
word--------------16
doubleword--------------32
quadword------------------------64
doublequadword---------------------------128
- 大的存储度量单位:
1千字节(kilobyte)等于2^10
或1024字节.
1兆字节(megabyte 1MB)等于2^20
或104 8576字节.
1吉字节(gigabyte 1GB)等于2^30
即1024³
或10 7374 1824字节.
1太字节(terabyte 1TB)等于2^50
或1125 8999 0684 2624字节.
1拍字节(petabyte 1PB)等于2^50
或1125 8999 0684 2624字节
- 无符号整数类型的取值范围和大小
类型 | 取值范围 | 按位计的存储大小 | 类型 | 取值范围 | 按位计的存储大小 |
---|---|---|---|---|---|
无符号字节 | 0到2^8-1 | 8 | 无符号四字 | 0到2^64-1 | 64 |
无符号字 | 0到2^16-1 | 16 | 无符号八字 | 0到2^128-1 | 128 |
无符号双字 | 0到2^32-1 | 32 |
1.2 无符号十六进制整数
大的二进制数读起来很麻烦,因此十六进制数字就提供了一种简便的方式表示二进制数据.十六进制中的一个数字就表示了四位二进制位,两个十六进制数字就能表达一个字节.一个十六进制数字表示的范围是0到15,所以用字母A到F来代表十进制数10到15.
- 下表列出每个4位二进制转换到十进制和十六进制数值
二进制 | 十进制 | 十六进制 | 二进制 | 十进制 | 十六进制 |
---|---|---|---|---|---|
0000 | 0 | 0 | 1000 | 8 | 8 |
0001 | 1 | 1 | 1001 | 9 | 9 |
0010 | 2 | 2 | 1010 | 10 | A |
0011 | 3 | 3 | 1011 | 11 | B |
0100 | 4 | 4 | 1100 | 12 | C |
0101 | 5 | 5 | 1101 | 13 | D |
0110 | 6 | 6 | 1110 | 14 | E |
0111 | 7 | 7 | 1111 | 15 | F |
下面例子说明了二进制数0001 0110 1010 0111 1001 0100
是如何与十六进制数16A794
等价!
1 | 6 | A | 7 | 9 | 4 |
---|---|---|---|---|---|
0001 | 0110 | 1010 | 0111 | 1001 | 0100 |
1.2.1 无符号十六进制到十进制的转换
十六进制数中,每一个数字位都代表了16的幂.这有助于计算一个十六进制整数的十进制值.假设用下表来对一个包含数字的十六进制编号
.则下面公式计了这个整数的十进制值:
- 这个表达式可以用到任意n位的十六进制整数:
-一般情况下,可以通过公式把基数为B的任何n为整数转换为十进制数:
- 比如:
十六进制数1234
就等于
,也就是十进制数4460
.
同样十六进制数3BA4
等于
,也就是十进制数15268
.
- 下表列出了16的幂从16^0到16^7的十进制值
16^n | 十进制值 | 16^n | 十进制 |
---|---|---|---|
16^0 | 1 | 16^4 | 6 5535 |
16^1 | 16 | 16^ | 10 4857 |
16^2 | 256 | 16^ | 1677 7216 |
16^3 | 4096 | 16^ | 2 6843 5456 |
1.2.2 无符号十进制到十六进制的转换
无符号十进制数转换到十六进制的过程,把这个十进制的数反复的除以16,每次取余数作为一个十六进制数字.例如下表列出了十进制数422转换为十六进制的步骤:
除法 | 商 | 余数 |
---|---|---|
422/16 | 26 | 6 |
26/16 | 1 | A |
1/16 | 0 | 1 |
上表中,余数列的数字安装从后往前排,组合为十六进制数的结果!上面十进制转换为十六进制是:1A6
.
1.2.3 十六进制加法
假设我们现在要将两个数X和Y相加,其基数为b.对他们的标号从低位开始到最高位(也就是从右向左计算),如果X和Y相加的值大于基数b.计算S1=(S1 MOD b)
在向高位产生一个进位1.当计算下一组X和Y时需要把低位的进位1加上.
比如:现在将两个十六进制数6A2
和49A
相加.在最低位上2 A=12(十进制数)
没有进位就用十六进制数C
表示这个数的和值.在中间位上A 9=19(十进制数)
,由于19>=16(基数)
所以有进位,再计算19 MOD 13 = 3
,并将第三位产生一个进位1.最后在高位计算1 6 4 = 11(十进制数)
,则在和数的第三位上为十六进制数B.所以整个和数的十六进制为B3C
.例如下表:
进位 1
X| 6 A 2
Y| 4 9 A
S| B 3 C
1.3 有符号二进制整数数
有符号二进制整数有正数和负数.在x86处理器中,MSB表示的是符号位:0表示正数,1表示负数.下图展示了32位正数和负数的和:
代码语言:javascript复制符号位
^
|
1000 0000 0000 0000 0000 0000 1111 0110 负数
0000 0000 0000 0000 0000 0000 0000 1010 正数
1.4 二进制补码
负正数用补码(two's-complement)表示时,使用的数学原理是:一个整数的补码是其加法逆元.(如果将一个数与其加法逆元相加,加过为0).
例如:如果表达式为A,B.则就可以很方便的将其转换为加法表达式:A (-B)
.
将一个二进制数按位取反(求补)在加1,就形成了它的补码.以8位二进制数0000 0001
为例,求其补码为1111 1110
,求补码过程如下:
初始值 0000 0001
第一步:按位取反 1111 1110
第二部:结果加一 1111 1110
0000 0001
和值:补码 1111 1111
1111 1111
是-1
的补码.补码操作是可逆的,因此1111 1111
的补码就是0000 0001
.
1.5 十六进制补码
十六进制的补码方法:将一个十六进制整数按位取反并加1,就生成了它的补码,一个简单的十六进制数字取反方法就是用15减去改数字.
代码语言:javascript复制例子1:从右往左 F-D=2即(F=15,D=13.15-13=2),15-3=C以此类推.
6A3D --> 95C2 1 --> 95C3
95C3 --> 6A3C 1 --> 6A3D
1.6 有符号二进制到十进制的转换
- 如果高位是1,则改数是补码.在次对其补码,得到其正数值.然后把这个数值看作无符号二进制数,并求它的十进制数值!
- 如果最高位是0,就将其视为无符号二进制数,并转换为十进制数.
例如:有符号二进制数1111 0000
的最高有效位是1,这意味着它是一个负数.首先要求它的补码,然后再将结果转换为十进制,转换步骤如下所示:
初始值 1111 0000
第一步:按位取反 0000 1111
第二步:结果加一 0000 1111
0000 0001
----------
第三步:补码结果 0001 0000
第四步:转换为十进制 16
由于初始值
1111 0000
是负数,因此其十进制为-16
.
1.7 有符号十进制到二进制的转换
- 有符号十进制整数转换为二进制的步骤如下:
- 把十进制整数的绝对值转换为二进制
- 如果十进制数是负数,则在第一步的基础上,求改二进制的补码.比如:十进制数
-43
转换为二进制的过程为: - 无符号
43
的二进制数表示为0010 1011
. - 由于初始值是负数,因此,求出
0010 1011
的补码1101 0101
(取反加一).这就是十进制数-43
的二进制表示.
1.8 有符号十进制到十六进制的转换
- 有符号十进制到十六进制的转换步骤如下:
- 把十进制整数的绝对值转换为十六进制.
- 如果十进制数是负数,则在第一步的基础上,求改十六进制的补码.
1.9 有符号十六进制到十进制的转换
- 有符号十六进制到十进制的转换步骤如下:
- 如果十六进制数是负数,求其补码,否则保持该数不变.
- 把第一步得到的整数转换为十进制.如果初始值是负数.则在该十进制整数的面前加负号.
- 通过检查十六进制的最高有效位(最高)位,就可以知道该数是正数还是负数,如果最高位
>=8
改数是负数.如果最高位<=7
,该数是正数.比如,十六进制数8A20
是负数,二7FD9
是正数.
2.0 最大值和最小值
n位有符号数只用n-1
来表示的范围.下面列出了有符号单字节,字,双字,四字,和八字的最大值和最小值.
类型 | 范围 | 存储位数 | 类型 | 范围 | 存储位数 |
---|---|---|---|---|---|
有符号字节 | -2^7到 2^7-1 | 8 | 有符号四字节 | -2^43到 2^63-1 | 64 |
有符号字 | -2^15到 2^15-1 | 16 | 有符号八字节 | -2^127到 2^127-1 | 128 |
有符号双字 | -2^31到 2^31-1 | 32 |
2.1 二进制减法
如果采用羽十进制减法相同的方法,那么从一个较大的二进制数中减去一个较小的无符号二进制数就很容易了.如下所示:
代码语言:javascript复制 0 1 1 0 1 (十进制数 13)
-0 0 1 1 1 (十进制数 7)
---------------
1.位0上的减法非常简单:
0 1 1 0 1
-0 0 1 1 1
---------------
0
2.下一个位置上执行(0-1),要向左边的相邻位借1.其结果是从2中减去1:
0 1 1 0 1
-0 0 1 1 1
---------------
1 0
3.再下一位上,又要向左边的相邻位借一位.并从2中减1:
0 1 1 0 1
-0 0 1 1 1
---------------
1 1 0
4.最后,最高两位都执行的是零减去零:
0 1 1 0 1
-0 0 1 1 1
---------------
0 0 1 1 0 (十进制 6)
执行二进制减法还有更简单的方法,即将被减去数的符号位取反.然后将两数相加.这个方法要求用一个额外的位保存数的符号.
例如:以上面计算的01101 - 00111
为例来试一下这个方法.首先将00111
按位取反11000
加1,得到11001
.然后把这两个二进制数值相加,并忽略最高位的进位.
0 1 1 0 1 ( 13)
1 1 0 0 1 (-7)
--------------
0 0 1 1 0 ( 6)
版权属于:龙之介大人
本文链接:https://cloud.tencent.com/developer/article/1619545
本站所有原创文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 您可以自由的转载和修改,但请务必注明文章来源和作者署名并说明文章非原创且不可用于商业目的。