补码的两个重要问题

时间:2022-08-31 14:13:56

(原码,反码,补码)人们习惯用二进制原码表示十进制数,而计算机只认二进制补码,补码的补码是原码,计算机被设计为正数的原码、反码、补码都一样。在计算机运算过程中,负数原码是通过转为补码来运算的,所以在计算机中任何数据都是通过【补码】的方式来存储数据的(因为原码无法区分正负)。

 

补码的两个重要问题

 

二进制转十进制,这个就是1*10零次方+.........1*10的n次方

二进制转十六进制,例如:二进制 1101 1111就是十六进制的CF,怎么快速算出答案呢?每4个二进制当成一个整体就很快出答案了,同理十六进制转二进制也可以用这样的方法实现快速转化。

二进制转八进制,例如:二进制110 011就是八进制的63,每3个二进制当成一个整体就很快出答案了,同理八进制转二进制也可以用这样的方法实现快速转化。

但是注意,不存在八进制与十六进制的快速转化,都是以二进制为媒介来实现转化的。

 

 

学补码主要是搞定两个问题(以C语言中的int类型为例):
1.求负数在计算机中的二进制表示方式(也就是负数的补码)(反码+1,若是负数前面补满1若是正数前面补0总之补满32位
2.给你一个补码推断出其十进制是什么数字(确定正负,如果是负则反码+1转为十六进制,转为十进制

 

1.求C语言int类型中-5的在计算机中是以什么二进制表示的?

0101(原)
1010(反)
(28个1)1011这是补码也是计算机中-5的存储方式。


进阶:求C语言int类型中-100的在计算机中是以什么二进制表示的?


十进制正整数100转十六进制是(64)转为二进制就是 110 0100(原)

1100100(原)
0011011(反)

(24个1)1001 1100(补)

0xFFFFFF9C

2.求补码(25个1)1001010代表的十进制数字。
(25个1)100 1010(补码)

(25个0)011 0101(取反)

011 0110(反码+1,这里已经反推出原码了)
十六进制的36 就是十进制的54,又因为前面25位是1是个负数所以,(25个1)1001010代表的十进制数字是-54

 

 

*重点难点、下面图A讨论八位二进制数(一个字节)所代表的十进制数范围

补码的两个重要问题

 

                       (图A)

 

分析下面C语言代码的执行结果:

补码的两个重要问题

一个char是内存占比是一个字节,也就是8位二进制数。

0x80是十六进制,也就是二进制的1000 0000,由于首位是1所以这是一个负数,1000 0000 “取反+1” 是 1000 0000也就是十进制的128,又因为是负数所以是-128.

ch = 128,由图A可知,一个字节表示的数字范围是 -128~127,所以ch = 128已经溢出了一个字节的数字范围了,因此计算机强制地认为128是1000 0000,由于首位是1这是一个负数,1000 0000 “取反+1” 是 1000 0000也就是十进制的128,又因为是负数所以是-128.

学习目标:

     在Vc++6.0中一个int类型(4个字节)的变量所存储的数字范围是多少(参考图A)?

         int类型变量所能存储的最大正整数用十六进制表示是:7FFFFFFF

         int类型变量所能存储的绝对值最大的负整数用十六进制表示是:80000000

       已知一个整数的二进制代码求原始的数字

       数字超过最大正整数会怎样(溢出)

       不同类型数据的相互转化(溢出只存变量类型的最大位数),比如int转char,本来是32位,结果咔嚓一以下只剩下8位,前面24位被计算机删除掉。

补充一个异或( ^ )的知识点,所谓异或就是两个进行运算的数字转为二进制后分别对应的数字不相同则结果为1,相同结果为0

下面以一个字节为例分析 5^-3(负数求反码补码时符号位不变)

5的二进制是 +0101

-3是负数,必须转为补码才能运算,-3的二进制原码是-0011,反码(-1100),补码(- 1101),下面补足8位进行运算

0000 0101

1111 1101

异或结果是 1111 1000(前面四位是符号位),转化后获得答案为十进制的 -8