一、补码小知识
(1)已知十进制求二进制
1、求正整数的二进制
除2取余,直至商为零,余数倒叙排列(先用十六进制过渡更方便);
例:172 --- 0xAC --- 10101100
2、求负整数的二进制
先求与该负数相对应的正整数的二进制代码,然后将所有位取反,末尾加1,不够位数时,左边补1;
例:-172,对应的正整数172的二进制为 1010 1100 ,取反加1的二进制为 0101 0100,即0x54,若-172定义的是一个整型(32位),则 0x54 在VC++ 6.0中以十六进制输出的结果为 FFFFFF54(这就是上面所说的“不够位数时左边补1”)。
3、求零的二进制
全是零。
(二)已知二进制求十进制
1、如果首位是0,则表明是正整数,按普通方法来求(先用十六进制过渡更方便);
例: 0011 1001 --- 0x39 --- 57
2、如果首位是1,则表明是负整数,将所有位取反,末尾加1,所得数字就是该负数的绝对值;
例:101 0110 取反加1 010 1010 --- 0x2A --- 42,所以101 0110 所代表的负数为-42。
注意:若该二进制的位数未达到所定义的数据类型的位数,则在VC++ 6.0中输入时,需在该二进制数之前补1至符合其对应的数据类型的位数。如101 0110 如果定义的是整型,则在输入时应在其前补1至32位,即写成0xFFFFFFd6。原因在于,对于一个32位的数据类型,如果位数没有达到,则其高位默认为0,那么该二进制数默认表示为正数而非负数。
3、如果全是零,则对应的十进制数字就是零
二、用补码来理解计算机中数据溢出的问题
问题:在VC++ 6.0中一个char类型的变量所能存储的数字范围是多少?
根据上面的补码知识,对于char数据类型,可得出如下八位二进制所代表的十进制示意图。
需要注意的是,此时最高位的0和1是正负数的表征。从图中可以看出char的取值范围是-128 -- 127,当数据溢出时,如char i = 129, 则计算机内部将得到129的二进制数1000 0001,并将其视为负数,最终以%d格式输出的数字便是-127了。这也解释了最开始学习计算机遇到的一些疑惑:为什么数据溢出时变成了负数。