在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。在数字系统中,常要求代码按一定顺序变化。例如,按自然数递增计数,若采用8421码,则数0111变到1000时四位均要变化,而在实际电路中,4位的变化不可能绝对同时发生,则计数中可能出现短暂的其它代码(1100、1111等)。在特定情况下可能导致电路状态错误或输入错误。使用格雷码可以避免这种错误。格雷码有多种编码形式。

格雷码有多种编码形式
十进制数 4位自然二进制码 4位典型格雷码
十进制余三格雷码
十进制空六格雷码 十进制跳六格雷码 步进码
0
0000
0000
0010
0000
0000
00000
1
0001
0001
0110
0001
0001
00001
2
0010
0011
0111
0011
0011
00011
3
0011
0010
0101
0010
0010
00111
4
0100
0110
0100
0110
0110
01111
5
0101
0111
1100
1110
0111
11111
6
0110
0101
1101
1010
0101
11110
7
0111
0100
1111
1011
0100
11100
8
1000
1100
1110
1001
1100
11000
9
1001
1101
1010
1000
1000
10000
10
1010
1111
----
----
----
----
11
1011
1110
----
----
----
----
12
1100
1010
----
----
----
----
13
1101
1011
----
----
----
----
14
1110
1001
----
----
----
----
15
1111
1000
---- ---- ---- ----
表中典型格雷码具有代表性。若不作特别说明,格雷码就是指典型格雷码,它可从自然二进制码转换而来。

转换方法

递归生成码表

这种方法基于格雷码是反射码的事实,利用递归的如下规则来构造:
  1. 1位格雷码有两个码字
  2. (n+1)位格雷码中的前2n个码字等于n位格雷码的码字,按顺序书写,加前缀0
  3. (n+1)位格雷码中的后2n个码字等于n位格雷码的码字,按逆序书写,加前缀1
  4. n+1位格雷码的集合 = n位格雷码集合(顺序)加前缀0 + n位格雷码集合(逆序)加前缀1
2位格雷码 3位格雷码 4位格雷码 4位自然二进制码
00
01
11
10
000
001
011
010
110
111
101
100
0000
0001
0011
0010
0110
0111
0101
0100
1100
1101
1111
1110
1010
1011
1001
1000
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111

异或转换

二进制码→格雷码(编码):
此方法从对应的n位二进制码字中直接得到n位格雷码码字,步骤如下:
  1. 对n位二进制的码字,从右到左,以0到n-1编号
  2. 如果二进制码字的第i位和i+1位相同,则对应的格雷码的第i位为0,否则为1(当i+1=n时,二进制码字的第n位被认为是0,即第n-1位不变)
公式表示:

 

(G:格雷码,B:二进制码)

例如:二进制码0101,为4位数,所以其所转为之格雷码也必为4位数,因此可取转成之二进位码第五位为0,即0 b3 b2 b1 b0。
0 xor 0=0,所以g3=0
0 xor 1=1,所以g2=1
1 xor 0=1,所以g1=1
0 xor 1=1,所以g0=1
因此所转换为之格雷码为0111

其实,从上述格雷码异或转换的方法可以得到一个简单易行的算法,例如,对于一个2进制比特不超过32位的整数x,它的格雷码即可表示为 (x>>1)^x。

算法演示:

#include <stdio.h>
#include <stdlib.h>
void print_bin(unsigned int value,char *tail); //打印一个数字的bit位int main(int argc,char* argv[])
{unsigned int temp;for(unsigned int i=0;i<=15;i++){printf("%-4d:",i);temp=(i>>1)^i;    //转换代码仅仅一行,很简单print_bin(temp,"\n");}return 0;
}void print_bin(unsigned int value,char* tail)
{for(int i=31;i>=0;i--){printf("%d",(value>>i)&1);}if(tail){printf("%s",tail);}
}

编译运行结果:

root@javis:~/Documents/Code$ gcc test.c -std=c99 -o test.out
root@javis:~/Documents/Code$ ./test.out
0   :00000000000000000000000000000000
1   :00000000000000000000000000000001
2   :00000000000000000000000000000011
3   :00000000000000000000000000000010
4   :00000000000000000000000000000110
5   :00000000000000000000000000000111
6   :00000000000000000000000000000101
7   :00000000000000000000000000000100
8   :00000000000000000000000000001100
9   :00000000000000000000000000001101
10  :00000000000000000000000000001111
11  :00000000000000000000000000001110
12  :00000000000000000000000000001010
13  :00000000000000000000000000001011
14  :00000000000000000000000000001001
15  :00000000000000000000000000001000

转载于:https://www.cnblogs.com/dongling/p/5726628.html

算法学习(6)----整数转换为格雷码相关推荐

  1. C语言学习:二进制码与格雷码的转换

    格雷码,又叫循环二进制码或反射二进制码,格雷码是我们在工程中常会遇到的一种编码方式,它的基本的特点就是任意两个相邻的代码只有一位二进制数不同. 格雷码的基本特点就是任意两个相邻的代码只有一位二进制数不 ...

  2. 结构光之格雷码编码加相移算法详解与实现(多种编码程序)

    格雷码+相移法既可以减少格雷码的编码位数,加快解码速度,也可以弥补单纯的相移法和格雷码法的对不连续位置难以重建的缺点. 操作过程如下: 采用格雷码与相移结合的时间编码方法,具体的编码方法为:首先向被测 ...

  3. 二进制与格雷码之间的转换的Verilog实现(更多一点的讨论)

    目录 前言 二进制码转换为格雷码的方法 格雷码转换为二进制码的过程 更多一点讨论之generate for 更多一点讨论之for 最后对格雷码的介绍 前言 以前的博客也有写这方面的内容,只是没有显式的 ...

  4. 格雷码在异步FIFO中的应用

    格雷码在异步FIFO中的应用 2018年7月1日 22点44分 1.格雷码的介绍 在介绍格雷码之前,我们先说说自然二进制码,也就是我们经常说的二进制数. 我们用二进制数表示一个变化的数值,例如,用一个 ...

  5. 数字电路基础知识——格雷码和二进制码的转换的算法和Verilog实现

    数字电路基础知识--格雷码和二进制码的转换的算法和Verilog实现 关于数字电路中的码制问题在这篇博客中已经做了详细分析, 数字电路基础知识--数字IC中的进制问题(原码,反码,补码以及各进制的转换 ...

  6. 【CSP 2019】格雷码

    输入文件:2019code.in 输出文件:2019code.out 时间限制:1 s 内存限制:256 MB [题目描述] 通常,人们习惯将所有 n 位二进制串按照字典序排列,例如所有 2 位二进制 ...

  7. 关于格雷码的规律、转换

    发现数电书中对于格雷码并没有很好地解释,这里保留下来所理解的知识供自己日后查看.这里主要说明排列规律和转换. 格雷码特点: 任意两个相邻的代码只有一位二进制数不同.并且首尾相连,属于循环码(这里我发现 ...

  8. FPGA异步时钟域处理之格雷码转换

    0 本章目录 1)时钟域定义 2)为什么要做跨时钟域的处理? 3)FPGA简介 4)结束语 1 时钟域定义 所谓时钟域,就是同一个时钟驱动的区域.单一时钟域是FPGA的基本组成部分,但是随着设计规模扩 ...

  9. 牛客网verilog刷题_VL47 格雷码计数器

    格雷码(gray code)的使用 在产生FIFO满信号时,要将写指针和读指针进行比较,由于两个指针分别在各自的时钟域,彼此之间是异步的,在使用二进制进行计数器实现指针时,就会导致用于比较的指针取样错 ...

最新文章

  1. 以二进制的形式查看文件 Linux之od命令详解
  2. UA MATH636 信息论5 信道编码简介
  3. 小米汽车计划在2024年上半年出车:第一年卖10万台
  4. **python基础类和对象(十二)
  5. 单IP无TMG拓扑Lync Server 2013:外部访问
  6. 用SDWebImage加载FLAnimatedImage
  7. 查看设置本机共享文件 net share
  8. 第D题 把手放在键盘上时,稍不注意就会往右错一位。
  9. FastDFS分布式架构,详细安装步骤,测试;Nginx中配置FastDFS,并提供优化,下载方法,楼主已测
  10. QT QListView
  11. win10系统服务器不能创建对象,win10系统中activex部件不能创建对象怎么修复
  12. 2020 dns排名_2020年中国最快的dns_动漫台
  13. 在python中如何读写txt文本文档
  14. [转载]Geronimo renegade: OpenEJB 和 Apache Geronimo 的 EJB 实现
  15. 流程图绘制工具 yEd
  16. Linux详细到爆炸的一篇文章
  17. xp系统总是弹出宽带连接服务器,如何处理xp电脑总是弹出宽带连接
  18. Attention mask理解
  19. kinectfusion的详细介绍
  20. Python每日笔记打卡_day3

热门文章

  1. 读取4:2:0格式YUV序列的Y分量、U分量以及V分量,并分别保存为.yuv格式(matlab实现)
  2. C++判断一个序列是否为堆(最大堆、最小堆)
  3. mysql 订单id格式_【mysql】订单规则id怎么生成?
  4. pacs文件浏览工具_啥?网络攻击浏览器让你惊惶失措?这里教你防患未然
  5. c语言无线网络抓包程序,c语言实现抓包
  6. YOLOv3: An Incremental Improvement
  7. 2013计算机二级试题,2013年3月全国计算机二级VFP真题
  8. java exception信息_可能通过Java Exceptions暴露敏感信息?
  9. virtualbox+vagrant快速创建虚拟机
  10. XDeepFM 模型,字节跳动短视频内容理解和推荐系统