关于负数在计算机中的表示方法讲述

萌到你眼炸
596次浏览
2021年02月21日 05:11
最佳经验
本文由作者推荐

-

2021年2月21日发(作者:大专学历)


负数的二进制编码


——


越是基础的越是要掌握< /p>



分类:



学习笔记


2010-02-15 13:18330

< p>
人阅读


评论


(0)


收藏举 报






原码


就是原来的表示方法



反码


是除符号位(最高位)外取反


< /p>


补码


=


反码


+1


以前学习二进制编码时,


老师讲了一堆堆的什么原码啊反码啊补 码



xxxx


转换啊,


还有负数的表示方式啊



总是记不零清,


终于从网


上找到了一种比较好的讲解方式,


保存再< /p>


share


一下,


不过为了系

< p>
统化讲解,


又找来了一些编码的基础知识,


如果只 想看负数编码记


忆法,请跳转到



1.


如果你不知道二进制怎么编码,请继续,否则请跳到


2



1


字节



=


8


位,所以它能表示的最大数当然 是


8


位都是


1


(既然


2



制的数只能是


0



1,


如果是我们常见的


10


进制,那就


8

位都为


9


,这


样说,你该懂了?)



1


字节的二进制数中,最大的数:< /p>


11111111




这个数的大小是多少呢?让我们来把它转换为十进制数。



无论是什么进制,都是左边是高位,右边是低位。


10


进制是我们


非常习惯的计数方式,第一位代表有几个


1


(即几个


10


0


,第二位


代表有几个


10


(即几个


10


1


)< /p>


,第三位代表有几个


100


(即有几个< /p>


10


2




,用小学课本上的说法就是:个位上的数表示几个


1


,十位


上的数表示向个


10


, 百位上的数表示几个


100


……



同理可证,二进制数则是:第


1


位数表示几 个


1



2


0



,第


2


位数 表


示几个


2



2


1




第< /p>


3


位数表示几个


4



2


2





4


位数表示向个

8(2


3


)


……

< br>


以前我们知道


1


个字节有


8


位,


现在通过计算


,


我们又得知:


1


个字节

< p>
可以表达的最大的数是


255


,也就是说表示


0~255



256


个数。



那么两个字节


(双字节数)


呢?双字节共


16


位。



11111



这个数并不大 ,


但长得有点眼晕,


从现在起,


我们要 学会这样来表


达二制数:



1111 1111 1111 1111,


即每


4


位隔一空格。



双字节数最大值为:



1 * 2


15


+ 1 *2


14


+ 1* 2


13


+ 1 * 2


12


+ 1 * 2


11


+ 1 * 2


10


+


……


+ 1 * 2


2


+


1 * 2


1


+ 1* 2


0


= 65535




很自然,我们可以想到,一种数据类型允许的最大值,和它的


位数有关。具体的计算方法方法是,如果它有


n


位,那么最大值


就是:



n


位二进制数的最大值:


1 * 2


(n-1)


+ 1 * 2


(n-2)


+ ... + 1 * 2


0



2


、理解有符号数和无符号数



负数在计算机中如何表示呢?这一点,你可能听过两种不同的回


答。< /p>





种是教科 书,它会告诉你:计算机用



补码


”< /p>


表示负数。可是有



< br>补码



的概念一说就得一节课,这一些我们需要在第


6


章中用一


章的篇幅讲

2


进制的一切。




者,




补码



表示负数,


其实是一种


公 式,


公式的作用在于告诉你,


想得到问题的答案,


应该如何计算。


却并没有告诉你为什么用这个公式就可以得到答案?



-----


我就是


被 这个弄混淆的


>_<





一种是一些程序员告诉你的:用二 进制数的最高位表示符号,


最高位是


0


,表示正数,最高位是


1


,表示负数。这种说法本身没


错,可是如果没有下文,那么它就是



错的。至 少它不能解释,为


什么字符类型的


-1


用二进制表示是



1111


1111



(16


进制为


FF)


;而


不是我们更能理解的


“< /p>


1000


0001


< br>。


(为什么说后者更好理解呢?


因为既然说最高位是


1


时表示负数,那


1000


0001


不是正好是


-1


吗 ?


-----re


!当初偶就是这么想的,

so


一直在脑中打架,越打越混


淆=,=

< br>)




让我们从头说起。



2.1


、你自已决定是否需要有正负。



就像我们必须决定某个量使用整数还是实数,


使用多大的范围数 一


样,


我们必须自已决定某个量是否需要正负。


如果这个量不会有负


值,那么我们可以定它为带正负的类型。

< br>


在计算机中,


可以区分正负的类型,

< br>称为有符类型,


无正负的类型


(只有正值)


,称为无符类型。



数值类型分为整型或实型,其中 整型又分为无符类型或有符类型,


而实型则只有有符类型。



字符类型也分为有符和无符类型。



比 如有两个量,年龄和库存,我们可以定前者为无符的字符类型,


后者定为有符的整数类型 。



2


、使用二制数中的最高位表示正负。



首先得知道最高位是哪一位?


1


个字节 的类型,如字符类型,最高


位是第


7


位 ,


2


个字节的数,最高位是第


15


位,


4


个字节的数,最高

< br>位是第


31


位。不同长度的数值类型,其最高位也就不同 ,但总是


最左边的那位(如下示意)


。字符类型固定是


1


个字节,所以最高


位总是第

< br>7


位。



(


红色为最高位


)


单字节数:



1


111 1111


双字节数:



1


111 1111 1111 1111


四字节数:



1


111 1111 1111 1111 1111 1111 1111 1111


当我们指定一个数量是


无符号 类型


时,那么其最高位的


1



0


,和


其它位一样,用来表示该数的大小。



当我们指定一个数量是


有符号类型


时,


此时,


最高数称为



符号位





1


时,表示该数为负值,为


0


时表示为正值。




3


、无符号数和有符号数的范围区别。



无符号数中,


所有的位都用于直接表示该值的大小。

< p>
有符号数中最


高位用于表示正负,所以,当为正值时,该数的最大值就会变 小。


我们举一个字节的数值对比:



无符号数:



1111 1111


值:


255 1* 2


7


+ 1* 2


6


+ 1* 2


5


+ 1* 2


4


+ 1* 2


3



+ 1* 2


2


+ 1* 2


1


+ 1* 2


0



有符号数:



0111 1111


值:


127 1* 2


6


+ 1* 2


5


+ 1* 2


4


+ 1* 2


3


+ 1* 2


2



+ 1* 2


1


+ 1* 2


0




< /p>


同样是一个字节,无符号数的最大值是


255

,而有符号数的最


大值是


127



原因是有符号数中的最高位被挪去表示符号了。


并且,


我们知道,最高位的权值也是最高的(对于


1


字 节数来说是


2



7



=128


< br>,所以仅仅少于一位,最大值一下子减半。



不过,


有符号数的长处是它可以表示负数。


因此,


虽然它的在最大


值缩水了,


却在负值的方向出现了伸展。


我们仍一个字节的数值对


比:



无符号数:



0 ----------------- 255


有符号数:



-128 --------- 0 ---------- 127




同样是一个字节,无符号的最小值是



0


,而有符号数的最小值是


-128


。所以二者能表达的不同的数值的个数都一样是


256


个。只不


过前者表达的是


0


255



256


个数,后者表达的是


-128



+127



256


个数。

< p>


一个有符号的数据类型的最小值是如何计算出来的呢?



有符号的数据类型的最大值的计算方法完全和无符号一样,


只不过


它少了一个最高位(见第


3


点)

< p>
。但在负值范围内,数值的计算方


法不能直接使用


1* 2


6


+ 1* 2


5



的公式进行转换。


在计算机中,


负数


除为最高位为

1


以外,还采用补码形式进行表达。所以在计算其值


前,需 要对补码进行还原。这里,先直观地看一眼补码的形式:



以我 们原有的数学经验,在


10


进制中:


1


表示正


1


,而加上负号:


-1


表示和


1


相对的负值 。



那么,我们会很容易认为在


2


进制中(


1


个字节)




0000


0001



示正


1


,则高位为< /p>


1


后:


1000 0001


应该表示


-1




然而,事实上计算机中的规定有些相反,请看下表:



二进制值(


1


字节)



1


000


0000

< br>红色的


1


代表负数


蓝色的



补码


(


补码


=


反码


+1)



-128



十进制值



1


000


0001

< br>蓝










-127


想化成负数?:先



值?:将补码还原为原码



< br>1



按位取反



1


000 0010


还原方法:补码< /p>


-1


再取反



-126



1


000 0011



...



1


111 1110



1


111 1111





首先我们看到,从


-1



-128


,其二进制的 最高位都是


1


(表中标为


红色)


,正如我们前面的学。



然后我们有些奇怪地发现,


1000


0000


并没有拿来表示



-0


;而


1000

< br>0001


也不是拿来直观地表示


-1

。事实上,


-1



1111 < /p>


1111



表示。



怎么理解这个问题呢?


先得问一句是


-1


大还是


-128







然是



-1


大。


-1


是最大的负整数。以此对应,计算机中无论是


字符类型,


或者是整数类型,


也无论这个整数是 几个字节。


它都用


-125



...



-2



-1




1


来表示



-1


。比如一个字节的数值中:


111 1 1111


表示


-1


,那么,


1111


1111


-


1


是什么呢?和现实中的计算结果完全一致。


1111


1111 - 1 = 1111 1110


,而


1111 1110


就是


-2


。这样一直减下去,当


减到只剩最 高位用于表示符号的


1


以外,其它低位全为

0


时,就是


最小的负值了,在一字节中,最小的负值是


1000


0000


,也就是


-128




------ --


小米批注:就是这部分蓝色的文字,让我终于能记清楚


-1



编码方式了,汗=。=


< p>
我们以


-1


为例,来看看不同字节数的整数中,如 何表达


-1


这个数:



字节数



二进制值



十进制值



-1




1


111


1111


红色表示负数


蓝色部




负数:原






来< /p>






法、反码





号位(最


高位)外


取反、补



=


反码


1

< br>111 1111 1111 1111



-1


分的


补码


为值


1


-


-


-


-


-


-


-


-