大家好,欢迎来到IT知识分享网。
意义
xxxx
几种编码及转换
几种编码都需要懂,而且分情况。使用这些编码的基本前提,是确定单位,比如这里探讨的是一个字节,还是int(例如java中的32位int)。
以下内容我们均假设为一个字节(8位)
原码及使用
几点特性:
- 符号位固定为标定符号,不参与表示数字大小
- 非符号位的位表示数字绝对值
- 有正负零
想写出原码,需要先确定数字。
我们知道,1个字节的原码是支持正负127范围内的整数的,包括从-127到-0到+0再到+127的这些整数。
+1
- 符号为正,所以符号位为
0
- 绝对值为
1
,所以非符号位为1
的二进制形式1
扩展6个0
,即0000001
所以,可以得到+1原码的表示形式:
0
0000001
-1
- 符号为负,所以符号位为
1
- 绝对值为
1
,所以非符号位为1
的二进制形式1
扩展6个0
,即0000001
所以,可以得到-1
原码的表示形式:
1
0000001
反码及使用
反码是不直接使用的,是原码和补码间的桥梁。
反码的计算方式
补码及使用
补码直接用于计算机的计算,特点是将减法转换成加法。
补码的计算方式
正数的补码=原码
负数的补码=原码的反码+1
深入理解编码本质
编码,顾名思义是由人类编的。兼有存在,意义,功能多重属性。
原码编码
原码的特点就是规定,在把一定的数位作为一个单元后,取其中的最高位(即书写中最左边的位)为符号位,0
表示正数,1
表示负数。然后剩余的位数用于表示数字的大小(即绝对值)。
反码及转换
这里,我们从一个例子来看。假设以两位长度二进制作为单位,我们见微知著的来分析。
原码 | 反码 | 补码 | 逻辑意义 |
---|---|---|---|
000 | 000 | 000 | +0 |
001 | 001 | 001 | +1 |
010 | 010 | 010 | +2 |
011 | 011 | 011 | +3 |
100 | 111 | 1([1]00) | ? |
101 | 110 | 111 | -1 |
110 | 101 | 110 | -2 |
111 | 100 | 101 | -3 |
为什么我们要在原码的100
对应的逻辑意义那里打一个问号呢?
因为我们看,逻辑意义中已经有了-3,-2,-1,+0,+1,+2,+3,再看这里的补码,其实是有一个进位的。
原码100
的补码是这样计算的:
- 先计算反码:
1
00 ->1
11 - 再计算补码:
1
11,对于其数值部分+1,即11
(2)+1
(2)=100
(2),因为1
进位了,而只保留两位,所以我们得到00
。再加上预留的符号位1
,就是:1
00
原码的100
对应的补码是100
,那么这个补码应该对应的意义也是-0
么?
我们已知-2
++2
=+0
=-0
计算:
-2
的补码是110
+2
的补码是010
相加得:1000
,其中高位1
溢出,剩下000
说明000
应该是0的补码表现形式
我们还已知-2
+-2
=-4
计算:
-2
的补码是110
-2
的补码是110
相加得:1100
,其中高位1
溢出,剩下100
所以,为了让计算规则自恰,我们说补码100
表示-4
所以,-4
的原码就是100
总结
回头来看这个表,我们会发现,应该加一个列在最右边
原码 | 反码 | 补码 | 逻辑意义 | 原码意义 |
---|---|---|---|---|
000 | 000 | 000 | 0 | +0 |
001 | 001 | 001 | +1 | +1 |
010 | 010 | 010 | +2 | +2 |
011 | 011 | 011 | +3 | +3 |
100 | 111 | 1([1]00) | -4 | -0 |
101 | 110 | 111 | -1 | -1 |
110 | 101 | 110 | -2 | -2 |
111 | 100 | 101 | -3 | -3 |
这里,原码
是计算机中实际存储的数据格式;原码意义
所列出的数值并不会被计算机用于将二进制转换为10进制;原码
都会被转换成补码
计算,计算机展示数字的时候,会将二进制数据按照逻辑意义
展现出来。
上表采用3位二进制数做说明,是为了方便列表理解。
考虑到实际使用中有大量使用到无符号字节,所以列一个简单的表格,方便大家理解,无符号字节(C语言中一般是unsigned char)和char类型表示的数值的区别
原码 | 反码 | 补码 | 作为unsigned char | 作为char |
---|---|---|---|---|
0000 0000 | 0000 0000 | 0000 0000 | 0 | +0 |
0000 0001 | 0000 0001 | 0000 0001 | 1 | +1 |
0111 1111 | 0111 1111 | 0111 1111 | 127 | +127 |
1000 0000 | 1111 1111 | 1000 0000 | 128 | -128 |
1000 0001 | 1111 1110 | 1111 1111 | 129 | -1 |
1111 1111 | 1000 0000 | 1000 0001 | 255 | -127 |
番外篇:为什么计算需要用补码,理论上为什么行?
举个例子,某一个数:
001
+111
我们将001
和111
都视为无符号数。
我们可以知道这样一个事实:
111
变成补码的过程是:
符号位不变,其余位取反:100
然后加1:101
我们将原码和补码进行3位以内的二进制加法:
111
+101
=1100
保留3位后,得到100
也就是:101
+111
=100
那么111
=100
–101
所以:
001
+101
=001
+100
–111
(1)
又因为110
+110
=100
(2)
(1)中带入(2)
001
+101
=001
+110
+110
–111
=。。。。。
好了,以上一小节是扯淡,后来发现真理了
拿8位二进制数做例子:
原码 | 反码 | 补码 | 作为unsigned char | 作为char |
---|---|---|---|---|
0000 0000 | 0000 0000 | 0000 0000 | 0 | +0 |
0000 0001 | 0000 0001 | 0000 0001 | 1 | +1 |
0000 0010 | 0000 0010 | 0000 0010 | 2 | +2 |
… | … | … | … | … |
0111 1111 | 0111 1111 | 0111 1111 | 127 | +127 |
1000 0000 | 1111 1111 | 1000 0000 | 128 | -128 |
1000 0001 | 1111 1110 | 1111 1111 | 129 | -1 |
1000 0010 | 1111 1101 | 1111 1110 | 130 | -2 |
… | … | … | … | … |
1111 1111 | 1000 0000 | 1000 0001 | 255 | -127 |
看起来好像char数值的顺序和原码的顺序不一致,其实就是这样的,因为char的数值是根据补码来计算,而补码是一个完全独立的编码,只不过和原码恰恰有一半重合,现在我们通过下面的表格来直接看补码。
补码 | 作为char |
---|---|
0111 1111 | +127 |
0111 1110 | +126 |
… | … |
0000 0010 | +2 |
0000 0001 | +1 |
0000 0000 | +0 |
1111 1111 | -1 |
1111 1110 | -2 |
… | … |
1000 0010 | -126 |
1000 0001 | -127 |
1000 0000 | -128 |
可以看出,对于负数:
补码转化为数值是:-2^7×1+非符号位绝对值
对于正数:
补码转化为数值是:-2^7×0+非符号位绝对值
所以,为什么转化为补码可以正常计算?因为补码是编码完全覆盖了连续整数范围且符号位能参与计算的编码。
- 两个正数的非符号位之和不产生向符号位的进位,即可使用加法器计算
- 两个负数的非符号位之和不产生向符号位的进位,即可使用加法器计算
- 一个正数一个负数,不可以直接使用加法器计算
对于补码来说
- 两个数使用加法器计算的结果,与其真实值直接相差n*模值
举例(3位二进制数):
补码 | 作为char |
---|---|
100 | -4 |
101 | -3 |
110 | -2 |
111 | -1 |
000 | 0 |
001 | +1 |
010 | +2 |
011 | +3 |
如上,可支持的数据范围是-4到+3
那么我们计算-2
+-3
即:
110
+101
=011
011
是+3,而-2
+-3
应该是-5
,我们发现:
+3
=-5
+4
×2
符合前面给定的特性。
结语
谢谢大家观看,有疑问欢迎留言。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/147469.html