一文搞懂 ZigZag 算法及 Go 语言的实现

2021-11-16  王中华 

所谓进制,就是当某一位上的信息满时,需要往前进位。比如,十进制,就是当某一位上的数满十时进位;而某一位上的数满二时进位就是二进制,等等。

进位之间都可以相互转化,例如:

十进制:10 → 二进制:1010 → 十六进制:A

我之前看过一个答案,说:为什么十进制比较通用?

因为咱人类只有 10 个手指头,数一遍刚好十个数,所以十进制自然就成为默认的进制。那如果人类长 11 手指头,说不定就是十一进制。

后来计算机的出现,一个数据的有无是最天然的信息承载单元,所以由 0 和 1 组成的二进制很自然成为计算机的进制方式。在此基础上,为了方便信息的使用,又采用了八进制、十六进制。

好了,进制这个东西就聊到这了。

三个东西
下来我们对一个十进制正整数表示为二进制,例如:十进制 10 等于二进制 1010。

那如果二进制表示一个负数,该怎么办?下来我们聊聊。

在计算机的世界里,定义了原码、反码和补码这几个东西。为了下来讲解简单点,我们假设使用一个字节(1Byte=8bits)表示一个数。

  1. 原码
    我们用第一个位表示符号( 0 为非负数,1 为负数),剩下的位表示值。例如:

+8 → 原:00001000
-8 → 原: 10001000

  1. 反码
    我们用第一位表示符号( 0 为非负数,1 为负数),剩下的位,非负数保持不变,负数按位求反。例如:

+8 → 原:0000 1000 → 反:0000 1000
-8 → 原:1000 1000 → 反:1111 0111
如果我们用原码或者补码来表示整数的二进制,有什么问题吗?表面上看,似乎挺好的。不过仔细思考就会发现两个问题:

第一,0 居然可以用两个编码表示,+0 和 -0。

原:0000 0000 → 1000 0000
反:0000 0000 → 1111 1111
第二,计算机不知道符号位的存在,因此参加运算后,会出现一个奇怪的现象。
ww2.mathworks.cn/matlabcentral/profile/authors/24712451?s_tid=gn_comm
ww2.mathworks.cn/matlabcentral/profile/authors/24712489?s_tid=gn_comm
ww2.mathworks.cn/matlabcentral/profile/authors/24712520
ww2.mathworks.cn/matlabcentral/profile/authors/24712542?s_tid=gn_comm
ww2.mathworks.cn/matlabcentral/profile/authors/24712563?s_tid=gn_comm

ww2.mathworks.cn/matlabcentral/profile/authors/24362830?s_tid=gn_comm
ww2.mathworks.cn/matlabcentral/profile/authors/24362863?s_tid=gn_comm
ww2.mathworks.cn/matlabcentral/profile/authors/24362863?s_tid=gn_comm
ww2.mathworks.cn/matlabcentral/profile/authors/24362914
ww2.mathworks.cn/matlabcentral/profile/authors/24373898
ww2.mathworks.cn/matlabcentral/profile/authors/24373950
ww2.mathworks.cn/matlabcentral/profile/authors/24374016
ww2.mathworks.cn/matlabcentral/profile/authors/24374060?s_tid=gn_comm
ww2.mathworks.cn/matlabcentral/profile/authors/24374107?s_tid=gn_comm
ww2.mathworks.cn/matlabcentral/profile/authors/24374137?s_tid=gn_comm
原码
1 + (-1)

→ 0000 0001 + 1000 0001

→ 1000 0010

53°|531 人阅读|0 条评论
登录 后发表评论
访客 25
2
0
0/0
0
博客
讨论
问答
找茬
王中华 的其他博文 更多