⼆进制的编码(原码、反码、补码)
⼆进制的编码(原码、反码、补码)
1.⼆进制怎么编码?
1字节 = 8位,所以它能表⽰的最⼤数当然是8位都是1(既然2进制的数只能是0或1,如果是我们常见的10进制,那就8位都为9)1字节的⼆进制数中,最⼤的数:11111111。
这个数的⼤⼩是多少呢?让我们来把它转换为⼗进制数。
⽆论是什么进制,都是左边是⾼位,右边是低位。10进制是我们⾮常习惯的计数⽅式,第⼀位代表有⼏个1(即⼏个100),第⼆位代表有⼏个10(即⼏个101),第三位代表有⼏个100(即有⼏个102)…,⽤⼩学课本上的说法就是:个位上的数表⽰⼏个1,⼗位上的数表⽰向个10,百位上的数表⽰⼏个100……
同理可证,⼆进制数则是:第1位数表⽰⼏个1 (20),第2位数表⽰⼏个2(21),第3位数表⽰⼏个4(22),第4位数表⽰向个8(23)……
以前我们知道1个字节有8位,现在通过计算,我们⼜得知:1个字节可以表达的最⼤的数是255,也就是说表⽰0~255这256个数。
那么两个字节(双字节数)呢?双字节共16位。 1111111111111111,这个数并不⼤,但长得有点眼晕,从现在起,我们要学会这样来表达⼆制数: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、理解有符号数和⽆符号数
负数在计算机中如何表⽰呢?这⼀点,你可能听过两种不同的回答。
⼀种是教科书,它会告诉你:计算机⽤“补码”表⽰负数。可是有关“补码”的概念⼀说就得⼀节课,⽤“补码”表⽰负数,其实⼀种公式,公式的作⽤在于告诉你,想得问题的答案,应该如何计算。却并没有告诉你为什么⽤这个公式就可以得到答案。
另⼀种是⼀些程序员告诉你的:⽤⼆进制数的最⾼位表⽰符号,最⾼位是0,表⽰正数,最⾼位是1,表⽰负数。这种说法本⾝没错,可是如果没有下⽂,那么它就是错的。⾄少它不能解释,为什么字符类型的-1⽤⼆进制表⽰是“1111 1111”(16进制为FF);⽽不是我们更能理解的“1000 0001”。(为什么说后者更好理解呢?因为既然说最⾼位是1时表⽰负数,那1000 0001不是正好是-1吗?)。让我们从头说起。
3、你⾃已决定是否需要有正负。
就像我们必须决定某个量使⽤整数还是实数,使⽤多⼤的范围数⼀样,我们必须⾃已决定某个量是否需要正负。如果这个量不会有负值,那么我们可以定它为带正负的类型。
在计算机中,可以区分正负的类型,称为有符类型,⽆正负的类型(只有正值),称为⽆符类型。
数值类型分为整型或实型,其中整型⼜分为⽆符类型或有符类型 (unsigned int, signed int),⽽实型float则只有有符类型。
字符类型也分为有符和⽆符类型 (unsigned char, signed char)。
4、使⽤⼆制数中的最⾼位表⽰正负。
⾸先得知道最⾼位是哪⼀位?1个字节的类型,如字符类型,最⾼位是第7位,2个字节的数,最⾼位是第15位,4个字节的数,最⾼位是第31位。不同长度的数值类型,其最⾼位也就不同,但总是最左边的那位(如下⽰意)。字符类型固定是1个字节,所以最⾼位总是第7位。(红⾊为最⾼位)
单字节数: 1111 1111
双字节数: 1111 1111 1111 1111
四字节数: 1111 1111 1111 1111 1111 1111 1111 1111
当我们指定⼀个数量是⽆符号类型时,那么其最⾼位的1或0,和其它位⼀样,⽤来表⽰该数的⼤⼩。
当我们指定⼀个数量是有符号类型时,此时,最⾼数称为“符号位”。为1时,表⽰该数为负值,为0时表⽰为正值。
5、⽆符号数和有符号数的范围区别。
⽆符号数中,所有的位都⽤于直接表⽰该值的⼤⼩。有符号数中最⾼位⽤于表⽰正负,所以,当为正值时,该数的最⼤值就会变⼩。我们举⼀个字节的数值对⽐:
⽆符号数: 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
同样是⼀个字节,⽆符号数的最⼤值是255,⽽有符号数的最⼤值是127。原因是有符号数中的最⾼位被挪去表⽰符号了。并且,我们知道,最⾼位的权值也是最⾼的(对于1字节数来说是2的7次⽅=128),所以仅仅少于⼀位,最⼤值⼀下⼦减半。
不过,有符号数的长处是它可以表⽰负数。因此,虽然它的在最⼤值缩⽔了,却在负值的⽅向出现了伸展。我们仍⼀个字节的数值对⽐:
⽆符号数: 0 ----------------- 255 0000 0000 ---------------1111 1111
有符号数: -128 --------- 0 ---------- 127 1000 0000 ----------------0111 1111
同样是⼀个字节,⽆符号的最⼩值是 0 ,⽽有符号数的最⼩值是-128。所以⼆者能表达的不同的数值的个数都⼀样是256个。只不过前者表达的是0到255这256个数,后者表达的是-128到+127这256个数。
6、⼀个有符号的数据类型的最⼩值是如何计算出来的呢?
有符号的数据类型的最⼤值的计算⽅法完全和⽆符号⼀样,只不过它少了⼀个最⾼位。但在负值范围内,数值的计算⽅法不能直接使⽤1* 2^6 + 1* 2^5 +...的公式进⾏转换。在计算机中,负数除为最⾼位为1以外,还采⽤补码形式进⾏表达。所以在计算其值前,需要对补码进⾏还原。这⾥,先直观地看⼀眼补码的形式:
以我们原有的数学经验,在10进制中:1 表⽰正1,⽽加上负号:-1 表⽰和1相对的负值。
那么,我们会很容易认为在2进制中(1个字节): 0000 0001 表⽰正1,则⾼位为1后:1000 0001应该表⽰-1。
然⽽,事实上计算机中的规定有些相反,请看下表:
⾸先我们看到,从-1到-128,其⼆进制的最⾼位都是1(表中标为红⾊),正如我们前⾯的学。
然后我们有些奇怪地发现,1000 0000 并没有拿来表⽰ -0;⽽1000 0001也不是拿来直观地表⽰-1。事实上,-1 ⽤1111 1111来表⽰。怎么理解这个问题呢?先得问⼀句是-1⼤还是-128⼤?
当然是 -1 ⼤。-1是最⼤的负整数。以此对应,计算机中⽆论是字符类型,或者是整数类型,也⽆论这个整数是⼏个字节。它都⽤全1来表⽰ -1。⽐如⼀个字节的数值中:1111 1111表⽰-1,那么,1111 1111 - 1 是什么呢?和现实中的计算结果完全⼀致。1111 1111 -1 = 1111 1110,⽽1111 1110就是-2。这样⼀直减下去,当减到只剩最⾼位⽤于表⽰符号的1以外,其它低位全为0时,就是最⼩的负值了,在⼀字节中,最⼩的负值是1000 0000,也就是-128。二进制编码转换
我们以-1为例,来看看不同字节数的整数中,如何表达-1这个数:
可能有同学这时会混了:为什么 1111 1111 有时表⽰255,有时⼜表⽰-1?所以我再强调⼀下:你⾃已决定⼀个数是有符号还是⽆符号的。写程序时,指定⼀个量是有符号的,那么 当这个量的⼆进制各位上都是1时,它表⽰的数就是-1;相反,如果事选声明这个量是⽆符号的,此时它表⽰的就是该量允许的最⼤值,对于⼀个字节的数来说, 最⼤值就是255。
7、个⼈总结
1000 0000表⽰-128是⼈为规定的,不然会有+0和-0之分
负数除最⾼位是1以外,还采⽤补码形式表达,所以在⼗进制计算前要对补码进⾏还原,即补码-1再取反。
计算机⽤补码表⽰负数:+128原码是1000 0000,反码是0111 1111,补码是0111 1111+1=1000 0000表⽰-128
对于有符号数:
1. 最⾼位四符号位,0表⽰整数,1表⽰负数
2. 正数的原码,反码,补码相同
3. 负数的反码=原码符号位不变,其他为取反
4. 负数的补码=它的反码+1
5. 0的反码,补码都是0
6. 计算机运算时,都是以补码的⽅式来运算的
example:1-2=1+(-2),在计算机中,1的补码:0000 0001,-2的原码:1000 0010,-2的反码:1111 1101,-2的补码:1111 1110,补码相加:0000 0001+1111 1110=1111 1111,再将结果转成原码(减1取反),减1得到反码:1111 1110,取反得到原码:1000 0001,转成原码后才能转成⼗进制结果:-1,-1的补码是1111 1111,1111 1111即-1在计算机中的表⽰。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论