格雷码简介

在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。格雷码(Gray Code)又称Grey Code、葛莱码、格莱码、戈莱码、循环码、反射二进制码、最小差错码等。

格雷码有多种编码形式

十进制数

4位自然二进制码

4位典型格雷码

十进制余三格雷码

十进制空六格雷码

十进制跳六格雷码

步进码

0

0000

0000

0010

0000

0000

00000

1

0001

0001

0110

0001

0001

00001

2

0010

0011

0111

0011

0011

00011

...

表中典型格雷码具有代表性。若不作特别说明,格雷码就是指典型格雷码,它可从自然二进制码转换而来。

为什么要使用格雷码?

格雷码是一种具有反射特性和循环特性的单步自补码,其循环和单步特性消除了随机取数时出现重大错误的可能,其反射和自补特性使得对其进行求反操作也非常方便,所以,格雷码属于一种可靠性编码,是一种错误最小化的编码方式,因此格雷码在通信和测量技术中得到广泛应用。

格雷码属于可靠性编码,是一种错误最小化的编码方式。因为,虽然自然二进制码可以直接由数/模转换器转换成模拟信号,但在某些情况,例如从十进制的3转换为4时二进制码的每一位都要变,能使数字电路产生很大的尖峰电流脉冲。而格雷码则没有这一缺点,它在相邻位间转换时,只有一位产生变化。它大大地减少了由一个状态到下一个状态时逻辑的混淆。由于这种编码相邻的两个码组之间只有一位不同,因而在用于方向的转角位移量-数字量的转换中,当方向的转角位移量发生微小变化(而可能引起数字量发生变化时,格雷码仅改变一位,这样与其它编码同时改变两位或多位的情况相比更为可靠,即可减少出错的可能性。

在数字系统中,常要求代码按一定顺序变化。例如,按自然数递增计数,若采用8421码,则数0111变到1000时四位均要变化,而在实际电路中,4位的变化不可能绝对同时发生,则计数中可能出现短暂的其它代码(1100、1111等)。在特定情况下可能导致电路状态错误或输入错误。使用格雷码可以避免这种错误。

格雷码是一种绝对编码方式,典型格雷码是一种具有反射特性和循环特性的单步自补码,它的循环、单步特性消除了随机取数时出现重大误差的可能,它的反射、自补特性使得求反非常方便。

由于格雷码是一种变权码,每一位码没有固定的大小,很难直接进行比较大小和算术运算,也不能直接转换成液位信号,要经过一次码变换,变成自然二进制码,再由上位机读取。

典型格雷码是一种采用绝对编码方式的准权码,其权的绝对值为2^i-1(设最低位i=1)。

格雷码的十进制数奇偶性与其码字中1的个数的奇偶性相同。

应用

格雷氏编码与相位移在三维曲面量测:利用格雷码投射在微型曲面做量测 一个非接触式、投影的方法光学测量。

在化简逻辑函数时,可以通过按格雷码排列的卡诺图来完成。

角度传感器:汽车制动系统有时需要传感器产生的数字值来指示机械位置。如图是编码盘和一些触点的概念图,根据盘转的位置,触点产生一个3位二进制编码,共有8个这样的编码。盘中暗的区域与对应的逻辑1的信号源相连;亮的区域没有连接,触点将其解释为逻辑0。使用格雷码对编码盘上的亮暗区域编码,使得其连续的码字之间只有一个数位变化。这样就不会因为器件制造的精确度有限,而使得触点转到边界位置而出现错误编码。

九连环问题:中国的古老益智玩具九连环有着和格雷码完全相同的数学模式,外国一款名为spin out的玩具也是运用相同的数学模式。智力玩具九连环的状态 变化符合格雷码的编码规律,汉诺塔的解法也与格雷码有关。九连环中的每个环都有上下两种状态,如果把这两种状态用0/1来表示的话,这个状态序列就会形成一种循环二进制编码(格雷码)的序列。所以解决九连环问题所需要的状态变化数就是格雷码111111111所对应的十进制数341。

二进制格雷码的生成

问题:产生n位元的所有格雷码字符串表示。

格雷码(Gray Code)是一个数列集合,每个数使用二进位来表示,假设使用n位元来表示每个数字,任两个数之间只有一个位元值不同。

例如以下为3位元的格雷码: 000 001 011 010 110 111 101 100 。

如果要产生n位元的格雷码,那么格雷码的个数为2^n。

直接排列

生成二进制格雷码方式1:以二进制为0值的格雷码为第零项,第一项改变最右边的位元,第二项改变右起第一个为1的位元的左边位元,第三、四项方法同第一、二项,如此反复,即可排列出n个位元的格雷码。

假设原始的值从0开始,格雷码产生的规律是:

第一步,改变最右边的位元值;

第二步,改变右起第一个为1的位元的左边位元;

第三步,第四步重复第一步和第二步,直到所有的格雷码产生完毕(换句话说,已经走了(2^n) - 1 步)。

用一个例子来说明:

假设产生3位元的格雷码,原始值位 000

第一步:改变最右边的位元值: 001

第二步:改变右起第一个为1的位元的左边位元: 011

第三步:改变最右边的位元值: 010

第四步:改变右起第一个为1的位元的左边位元: 110

第五步:改变最右边的位元值: 111

第六步:改变右起第一个为1的位元的左边位元: 101

第七步:改变最右边的位元值: 100

镜射排列

生成二进制格雷码方式2:n位元的格雷码可以从n-1位元的格雷码以上下镜射后加上新位元的方式快速的得到,如图所示。

如果按照直接排列规则来生成格雷码,是没有问题的,但是这样做太复杂了。如果仔细观察格雷码的结构,我们会有以下发现:

1、除了最高位(左边第一位),格雷码的位元完全上下对称(看下面列表)。比如第一个格雷码与最后一个格雷码对称(除了第一位),第二个格雷码与倒数第二个对称,以此类推。

2、最小的重复单元是 0 , 1。

000

001

011

010

110

111

101

100

所以,在实现的时候,我们完全可以利用递归,在每一层前面加上0或者1,然后就可以列出所有的格雷码。

比如:

第一步:产生 0, 1 两个字符串。

第二步:在第一步的基础上,正向每一个字符串都分别加上0,然后反向迭代每一个字符串都加上1,但是每次只能加一个,所以得做两次。这样就变成了 00,01,11,10 (注意对称)。

第三步:在第二步的基础上,再给每个字符串都加上0和1,同样,每次只能加一个,这样就变成了 000,001,011,010,110,111,101,100。这样就把3位元格雷码生成好了。

如果要生成4位元格雷码,我们只需要在3位元格雷码上再加一层0,1就可以了: 0000,0001,0011,0010,0110,0111,0101,0100,1100,1101,1110,1010,0111,1001,1000.

也就是说,n位元格雷码是基于n-1位元格雷码产生的。

[格雷码维基百科]

其它方法

利用卡诺图生成

利用卡诺图相邻两格只有一位变化以及卡诺图的变量取值以低阶格雷码的顺序排布的特征,可以递归得到高阶格雷码。由于此方法相对繁琐,使用较少。生成格雷码的步骤如下:

将卡诺图变量分为两组,变量数目相近(最好相等)

以逻辑变量高位在左低位在右建立卡诺图

从卡诺图的左上角以之字形到右上角最后到左下角遍历卡诺图,依次经过格子的变量取值即为典型格雷码的顺序

利用二进制码转换

转换方法参考下面吧。

格雷码和二进制码的转换

自然二进制码与格雷码的对照表:

十进制数

自然二进制数

格雷码

十进制数

自然二进制数

格雷码

0

0000

0000

8

1000

1100

1

0001

0001

9

1001

1101

2

0010

0011

10

1010

1111

3

0011

0010

11

1011

1110

4

0100

0110

12

1100

1010

5

0101

0111

13

1101

1011

6

0110

0101

14

1110

1001

7

0111

0100

15

1111

1000

二进制码转换成二进制格雷码

二进制码转换成二进制格雷码,其法则是保留二进制码的最高位作为格雷码的最高位,而次高位格雷码为二进制码的高位与次高位相异或,而格雷码其余各位与次高位的求法相类似。

二进制码 ----> 格雷码(编码):从最右边一位起,依次将每一位与左边一位异或(XOR),作为对应格雷码该位的值,最左边一位不变(相当于左边是0)。

Note: 这样做可行的原因,是因为二进制码每次+1时最多只有一个相邻的两个bit对的异或值会发生改变。

公式表示:G:格雷码 B:二进制码

整个数G(N) = (B(n) >> 1) XOR B(n)

单个位

格雷码转换成二进制码

二进制格雷码转换成二进制码,其法则是保留格雷码的最高位作为自然二进制码的最高位,而次高位自然二进制码为高位自然二进制码与次高位格雷码相异或,而自然二进制码的其余各位与次高位自然二进制码的求法相类似。

公式表示:

格雷码转换为二进制码算法有以下几种表述形式:

表述一:

二进制格雷码为Gn-1Gn-2...G2G1G0

自然二进制码为Bn -1Bn-2...B2B1B0

其中:最高位保留  Bn-1=Gn-1

其他各位  Bi-1=Gi-1 xor Bi ,i=1,2,...,n-1

表述二:

Bi = ˆG[n-1:i]=G[n-1]ˆG[n-2]ˆ..ˆG[i],i=0,1,...,n-1

表述三:

Bi = ˆ(G>>i),i=0,1,...,n-1

二进制格雷码字符串生成

c++ stl递归和非递归代码

vector gray0(int n) {

/*

* 格雷码字符串的直接排列递归实现

* 思路:1、获得n-1位生成格雷码的数组

* 2、由于n位生成的格雷码位数是n-1的两倍,故只要在n为格雷码的前半部分加0,后半部分加1即可。

*/

if (n == 0)

return vector{"0"};

else if (n == 1) {

return vector({"0", "1"});

} else {

vector new_gray_code;

vector gray_code = gray0(n - 1);

// vector gray_code = vector({"0", "1"});

vector::iterator gc_it;

for (gc_it = gray_code.begin(); gc_it != gray_code.end(); gc_it++)

new_gray_code.push_back("0" + *gc_it);

vector::reverse_iterator gc_rit;

for (gc_rit = gray_code.rbegin(); gc_rit != gray_code.rend(); gc_rit++)

new_gray_code.push_back("1" + *gc_rit);

return new_gray_code;

}

}

vector gray1(int n) {

/*

* 格雷码字符串的镜射排列非递归实现

*/

if (n == 0)

return vector{"0"};

vector gray_code = vector({"0", "1"});

while (--n) {

vector new_gray_code;

vector::iterator gc_it;

for (gc_it = gray_code.begin(); gc_it != gray_code.end(); gc_it++)

new_gray_code.push_back("0" + *gc_it);

vector::reverse_iterator gc_rit;

for (gc_rit = gray_code.rbegin(); gc_rit != gray_code.rend(); gc_rit++)

new_gray_code.push_back("1" + *gc_rit);

gray_code = new_gray_code;

}

return gray_code;

}

格雷码还有一种实现方式是根据这个公式来的 G(n) =  B(n) XOR B(n+1), 这也是格雷码和二进制码的转换公式。代码如下:

public void getGrayCode(int bitNum){

for(int i = 0; i < (int)Math.pow(2, bitNum); i++){

int grayCode = (i >> 1) ^ i;

System.out.println(num2Binary(grayCode, bitNum));

}

}

public String num2Binary(int num, int bitNum){

String ret = "";

for(int i = bitNum-1; i >= 0; i--){

ret += (num >> i) & 1;

}

return ret;

}

格雷码&lpar;Gray code&rpar;仿真

作者:桂. 时间:2018-05-12  16:25:02 链接:http://www.cnblogs.com/xingshansi/p/9029081.html 前言 FIFO中的计数用的是格雷码, ...

Android源码下载方法详解

转自:http://www.cnblogs.com/anakin/archive/2011/12/20/2295276.html Android源码下载方法详解 相信很多下载过内核的人都对这个很熟悉 ...

ANDROID自定义视图——onMeasure,MeasureSpec源码&&num;160&semi;流程&&num;160&semi;思路详解

简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量--onMeasure():决定View的大小 2.布局--onLayout():决定View在ViewGroup中的位置 3. ...

&lbrack;Spark內核&rsqb; 第41课:Checkpoint彻底解密:Checkpoint的运行原理和源码实现彻底详解

本课主题 Checkpoint 运行原理图 Checkpoint 源码解析 引言 Checkpoint 到底是什么和需要用 Checkpoint 解决什么问题: Spark 在生产环境下经常会面临 T ...

【Java】HashMap源码分析——常用方法详解

上一篇介绍了HashMap的基本概念,这一篇着重介绍HasHMap中的一些常用方法:put()get()**resize()** 首先介绍resize()这个方法,在我看来这是HashMap中一个非常 ...

【转】ANDROID自定义视图——onMeasure,MeasureSpec源码 流程 思路详解

gray code java_格雷码Gray Code详解相关推荐

  1. Android 8.0学习(32)---Android 8.0源码目录结构详解

    Android 8.0源码目录结构详解 android的移植按如下流程:     (1)android linux 内核的普通驱动移植,让内核可以在目标平台上运行起来.     (2)正确挂载文件系统 ...

  2. Spring IoC源码:getBean 详解

    文章目录 Spring源码系列: 前言 正文 方法1:getObjectForBeanInstance 方法2:getObjectFromFactoryBean 方法3:doGetObjectFrom ...

  3. python状态码及其含义_Shell退出状态码及其应用详解

    Shell 中运行的命令会使用0-255之间的整数值,作为退出状态码,并以此来告知shell该命令执行的状态.通常情况下,约定0代表命令成功结束,非0代表程序非正常退出. 典型退出状态码及其含义 退出 ...

  4. Android4.0源码目录结构详解

    Android4.0源码目录结构详解 Android4.0与2.1目录差不多 alsa这块,注意external/tinyalsa下有: include/tinyalsa/asoundlib.h mi ...

  5. python生成二维码_python生成二维码的实例详解

    python生成二维码的实例详解 版本相关 操作系统:Mac OS X EI Caption Python版本:2.7 IDE:Sublime Text 3 依赖库 Python生成二维码需要的依赖库 ...

  6. FreeRTOS之源码 及 移植详解

    源:FreeRTOS之源码 及 移植详解 转载于:https://www.cnblogs.com/LittleTiger/p/9117856.html

  7. 第41课:Checkpoint彻底解密:Checkpoint的运行原理和源码实现彻底详解

    第41课:Checkpoint彻底解密:Checkpoint的运行原理和源码实现彻底详解 一:Checkpoint到底是什么? 1,  Spark在生产环境下经常会面临Tranformations的R ...

  8. Nginx源码包安装详解

    源码包安装详解 1.源码获取 2.如何安装源码 3.源码获取存放 3.1创建源码存放目录 3.2把源码移到需要存放的目录 3.3解压文件 3.4常用命令介绍 4.源码安装实际操作 4.1官网获取源码包 ...

  9. 原码, 反码, 补码 详解(转载)

    原码, 反码, 补码 详解(转载) 繁星*墨菲 于 2020-05-23 10:22:53 发布1015 收藏 75 版权 转载地址:原码, 反码, 补码 详解 - ziqiu.zhang - 博客园 ...

最新文章

  1. python多线程的几种方法
  2. BZOJ1575: [Usaco2009 Jan]气象牛Baric
  3. python编程语言能干什么-python编程语言的优势与劣势--python能干啥
  4. 【opencv】11.旋转、翻转图片
  5. wkhtmltopdf:wkhtmltopdf(将html转换成pdf的利器)简介、安装、使用方法详细攻略
  6. ArcGIS鼠标滚轮方向之ArcMap篇
  7. win7 没有microsoft print to pdf_现在还能不能下载到正版WIN 7
  8. 单元测试junit参数_使用Junit参数在更少的时间内编写更好的单元测试
  9. layui表格checkbox选择全选样式及功能
  10. 【李宏毅机器学习】Why Deep Learning(p15) 学习笔记
  11. Hinton老爷子CapsNet再升级,结合无监督,接近当前最佳效果
  12. Neotec WELLFLO V8.1.6 油气井生产 模拟软件
  13. html都是纯文本文件吗,关于“什么是纯文本文件”的思考
  14. 详解无人驾驶汽车工作原理及关键技术。
  15. CREO图文教程:三维设计案例之一腔多模设计(定位参照零件导入模具模型)图文教程之详细攻略
  16. 计算机专业英语思维导图
  17. 微信小程序---tab选项卡组件
  18. java JDBC编程
  19. 2020最新抖音上热门技巧你知道了几个?
  20. 解决QML debugging is enabled.Only use this in a safe environment.警告

热门文章

  1. 时代的发展,带来的是淘汰还是机会
  2. 微信未验证应用(微信openSDK1.8.6的集成)
  3. 删除MAC启动台上无效的图标
  4. 基于ARM架构Cortex-A7 IMX6ULL 核心板设计核酸自动提取仪显控解决方案
  5. 2022-2028年全球糖酶行业收入年复合增长率CAGR为 4.6%
  6. 在一些测试的时候,我总是被考“思维定势”的题目给难住
  7. html 点击后上下滚动效果,css 上下滚动效果
  8. Oracle Spatial的空间查询,代码操作
  9. 车载红外夜视「升温」
  10. 能把音频转换成文字的软件推荐,快收藏起来