版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MonaLisaTearr/article/details/80609798
在计算机中,保存数据的方式目前来说那就是二进制,那么接下来我们就讨论下正负数在二进制中的表示方式,其中涉及到的概念有符号位、原码补码、反码等。相信大家在大学的时候多多少少都听过那么补码跟反码的概念,特别是计算机相关专业的,但是可能有很多朋友并没有没有真去使用过,所以到所致了知其然不知其所以然的情况出现,那么接下来分享下个人的理解!
一、二进制
1、在计算机中如果我们需要将1用十六位二进制表示那么如下:(在计算机中具体多少位要看cpu,这里我们先假设是16位)
1的十六位二进制:0000 0000 0000 0001
那么问题就来了,那-1怎么表示,于是聪明的科学家们就提出了符号位的说法,他们就将高位作为符号位使用,符号位为1就表示负数,符号位为0就表示正数所以就有了如下的表示。
1的十六位二进制:0000 0000 0000 0001
-1的十六位二
进制:1000 0000 0000 0001
2、这样看起来就没有什么问题的,也一目了然,一眼就分辨出来二级制数据的正负。但是我们不妨做下运算。
正常情况下,我们使用两个正数相加的时候如下:
0000 0000 0000 0001
+ 0000 0000 0000 0001
——————————————
0000 0000 0000 0010
结果完全没问题,确实是1+1=2
但是大家不妨用正数加负数看下
0000 0000 0000 0001
+ 1000 0000 0000 0001
——————————————
1000 0000 0000 0010
发现问题了吧,符号位为1,也就是说是-1+1=-2,很显然是错的,读书那会老师就告诉我们-1+1=0才是正确的,那么接下来看看科学家们怎么解决这个问题。
二、原码、反码、补码
为了解决上面出现的-1+1=-2的问题,我们的科学家又提出了反码跟补码的概念,那下面讲讲什么是反码跟补码。
1、对于正数
原码、反码、补码是一致的,如下:
1的十六位二
进制原码:0000 0000 0000 0001
1的十六位二
进制反码:0000 0000 0000 0001
1的十六位二
进制补码:0000 0000 0000 0001
2、对于负数
-1的原码如下:
-1的十六位二
进制原码:1000 0000 0000 0001
反码就是在原码的基础上保持符号位不变,其它位取反,如下:
-1的十六位二
进制反码:1111 1111 1111 1110
补码就是在反吗的基础上+1,如下
-1的十六位二
进制补码:1111 1111 1111 1111
结论就是:一个负数的补码=反码+1(注意这个结论也使用与从补码转回原码!)
3、好了,有来反码跟补码,那么科学家们就说了,你们不要按照原来的样子加了,你们用补码做加法运算,这样就不会错了,于是就有了下面-1+1的运算方式:
0000 0000 0000 0001
+ 1111 1111 1111 1111
——————————————
1 0000 0000 0000 0000
于是就有了1 0000 0000 0000 0000这个结果,由于我们这里是十六位二进制的运算,所以最高位的1溢出了,所以会被去掉,剩下:0000 0000 0000 0000,最高位为0,所以是正数,我们前面说过正数的补码、原码跟反码是一致的,所以最后结果是0000 0000 0000 0000
这里要注意的一点就是,我们用补码计算出来的结果也是补码,所以我们要还原成原码之后才是我们需要的结果,这时候我们就需要根据最高位是0还是1做出相应的转换了。
三、减法运算
上面我们强调的是-1+1,但是有的朋友可能会问,那减法怎么办?比如说-1-1,其实我们不妨换个角度考虑,何不把-1-1看成-1+(-1)?这两个表达式效果一样的吧?
1、由上面面我们知道-1的补码是1111 1111 1111 1111,所以就有了下面的计算方式:
1111 1111 1111 1111
+ 1111 1111 1111 1111
——————————————
1 1111 1111 1111 1110
将溢出为去掉得:1111 1111 1111 1110,此时的结果为补码,保持符号为不变取反+1得:1000 0000 0000 0010,最后结果为-2,,毫无问题。
所以当我们需要进行减法运算并涉及负数的时候,不防转换成加法去做,事实上cpu在运算设计上也是怎么做的。
(最后多提一嘴,运算的过程中使用的都是补码,在得到计算结果后再进行还原即可)
好了,今天分享就那么多了,希望对大家有帮助!!!