格雷码实现

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

转换方法

递归生成码表

这种方法基于格雷码是反射码的事实,利用递归的如下规则来构造:

  1. 1位格雷码有两个码字
  2. (n+1)位格雷码中的前2n个码字等于n位格雷码的码字,按顺序书写,加前缀0
  3. (n+1)位格雷码中的后2n个码字等于n位格雷码的码字,按逆序书写,加前缀1

异或转换

二进制码→格雷码(编码):

二进制码→格雷码(解码):

程序实现

1.异或转换

 1 #include <iostream>
 2 #include <vector>
 3 #include <string>
 4 #include <cmath>
 5 #include <math.h>
 6 using namespace std;
 7 // 十进制转二进制/
 8 // intput:十进制数字,和所需的位数
 9 // output:二进制字符串
10 string num2Binary(int num,int bitNum);
11
12 // 实现n位格雷码
13 // intput:格雷码的位数
14 // output:graycode
15 void getGrayCode(int bitNum);
16 void getGrayCode2(int bitNum,vector<string> &grayCode);//实现实参的改变要用引用
17
18 int main()
19 {
20     int m=35;
21     string c=num2Binary(m,8);
22     cout<<c<<endl;
23      vector<string> rel;
24     /*getGrayCode(4);*/
25     getGrayCode2(4,rel);
26     for (vector<string>::size_type i=0;i!=rel.size();i++)
27     {
28         cout<<rel[i]<<endl;
29     }
30     return 0;
31 }
32
33 void getGrayCode(int bitNum)
34 {
35     string grayCode;
36     for (int i=0;i<pow(2,bitNum);i++)
37     {
38         int temp=(i>>1)^i;
39         grayCode=(num2Binary(temp,bitNum));
40         cout<<grayCode<<endl;
41     }
42 }
43
44 void getGrayCode2(int bitNum,vector<string> &grayCode)
45 {
46     for (int i=0;i<pow(2,bitNum);i++)
47     {
48         int temp=(i>>1)^i;
49         string str=num2Binary(temp,bitNum);
50         grayCode.push_back(str);
51         /*cout<<grayCode[i]<<endl;*/
52     }
53 }
54 string num2Binary(int num,int bitNum)
55 {
56     string str;
57     string result="";
58     for (int i=bitNum-1;i>=0;i--)
59     {
60         int x=(num>>i)&1;
61         stringstream ss;
62         ss<<x;
63         ss>>str;
64         result+=str;
65         /*str.clear();*/
66     }
67     return result;
68 }

2.递归码表实现

 1 vector<string> getGrayCode3(int bitNum)
 2 {
 3     vector<string> grayCode(pow(2,bitNum));
 4     if (bitNum==1)
 5     {
 6         grayCode[0]="0";
 7         grayCode[1]="1";
 8         return grayCode;
 9     }
10     else
11     {
12         vector<string> lastGrayCode=getGrayCode3(bitNum-1);
13         for (vector<string>::size_type i=0;i!=lastGrayCode.size();i++)
14         {
15             grayCode[i]="0"+lastGrayCode[i];
16             grayCode[grayCode.size()-1-i]="1"+lastGrayCode[i];
17         }
18         for (vector<string>::size_type j=0;j!=grayCode.size();j++)
19         {
20             cout<<grayCode[j]<<endl;
21         }
22         return grayCode;
23     }
24
25 }

时间: 2024-10-03 14:35:47

格雷码实现的相关文章

连环锁 格雷码知识+大数

连环锁 题目抽象:某个格雷码到另一个格雷码最少需要的转换步数. 思路:直接求出对应得十进制,相减取绝对值. 当n=2时变换的序列为00,01,11,10 当n=3时变换的序列为000,001,011,010,110,111,101,100 …… 仔细观察发现这正是格雷码,相邻两个状态只有一位不同(实际上题目描述已经说了这个条件)! 十进制数 自然二进制数 格雷码 0 0000 0000 1 0001 0001 2 0010 0011 3 0011 0010 4 0100 0110 5 0101

【格雷码】

/* 格雷码 说明: Gray Code是一个数列集合 ,每个数使用二进位来表示 ,假设使用n位元来表示每个数好了 ,任两个数之间只有一个位元值不同, 例如以下为3位元的Gray Code: 000 001 011 010 110 111 101 100 由定义可以知道,Gray Code的顺序并不是唯一的,例如将上面的数列反过来写,也是一组GrayCode: 100 101 111 110 010 011 001 000 Gray Code是由贝尔实验室的Frank Gray在1940年代提出

FPGA学习笔记之格雷码、边沿检测、门控时钟

一.格雷码 格雷码的优点主要是进位时只有一位跳变,误码率低. 1.二进制转格雷码 我们观察下表: 二进制码 格雷码 00 00 01 01 10 11 11 10 二进制码表示为B[],格雷码表示为G[],则有 G(i) = B(i),i为最高位 G(i-1) = B(i) xor B(i-1),i非最高位 用verilog可以这样写 1 reg [WIDTH-1:0] bin; 2 reg [WIDTH-1:0] gray; 3 parameter WIDTH = 8; 4 always @(

格雷码的实现

问题:产生n位元的所有格雷码. 格雷码(Gray Code)是一个数列集合,每个数使用二进位来表示,假设使用n位元来表示每个数字,任两个数之间只有一个位元值不同. 例如以下为3位元的格雷码: 000 001 011 010 110 111 101 100 . 如果要产生n位元的格雷码,那么格雷码的个数为2^n. 假设原始的值从0开始,格雷码产生的规律是:第一步,改变最右边的位元值:第二步,改变右起第一个为1的位元的左边位元:第三步,第四步重复第一步和第二步,直到所有的格雷码产生完毕(换句话说,已

生成格雷码 转自leetcode

在一组数的编码中,若两个相邻的代码中只有一个二进制数不同,则称这种编码为格雷码. 下面尝试使用递归的方法来生成格雷码 vector<int> GrayCode(int n){//n表示格雷码的位数 if(n==0) return vector<int>(1)//返回只有一个0的容器 vector<int> res=GrayCode(n-1);//采用递归方法 for(int i=res.size()-1 ; i >=0 ;i-- )//采用从后往前的方式 res.

格雷码

*/--> pre.src {background-color: Black; color: White;} 格雷码 void gray_create(int n) { int a[n]; for (int i = 0; i < (i<<n); i++) { a[i] = i^(i>>1); } for (int i = 0; i < n; i++) { printf("%d\n", a[i]); } } Date: 2015-01-23 00

判断两个byte是否互为格雷码。

如果两个byte的二进制表示中仅有一位不同,则它们互为格雷码,写个函数判断两个byte是否互为格雷码. public class IsCogray { public boolean isCogray(char a, char b) { int m = a ^ b; return m != 0 && (m & (m - 1) & 0xff) == 0; } public static void main(String[] args) { IsCogray ic = new I

v3学院 FPGA专家 带你学习FPGA实现格雷码跨时钟域异步fifo

当由慢时钟域到快时钟域,肯定需要一个buffer做缓冲,这样才能完成时钟域的转换.一般这种情况都选择FIFO来做缓冲. 当读写FIFO的时钟不同那么称为异步FIFO,FIFO就是一个"环形存储器"读操作会把读指针指向下一个读数据,写操作会把写指针指向下一个写数据地址.当读指针追上写指针时称作读空,当写地址追上读地址时称作写满. 读空,写满标志的产生 格雷码地址编码产生 异步fifo整体逻辑框图 请扫二维码加入fpga圈 代码实现请持续关注,下次讲解! 本文章原创,来自v3学院 www.

格雷码输出

格雷码打印:打印出0~2n-1数,且相邻两个数只有一位不同. #include<iostream> #include<vector> using namespace std; int main() { int n; cin>>n; vector<int> result; result.push_back(0); for(int i=0;i<n;i++) { int high_bit=1<<i; for(int j=result.size()

格雷码计数器

简介 实现FIFO存储器读写指针比较好的方法就是使用格雷码计数器.格雷码计数器的优势在于其相邻两个数值之间只有一位发生变化,提高了系统的抗干扰能力,而且在计数时,各个输出的门电路翻转次数要远远小于二进制计数器,从而可以大幅度降低系统的功耗. 实现格雷码计数器的步骤如下: 将格雷值转换为二进制值. 根据条件递增二进制值. 将二进制值转换为格雷码 将计数器的最终格雷值保存到寄存器中. 格雷码转二进制 格雷码转二进制的公式如下: binn?1=grayn?1bini=grayi?bini+1 格雷码转