کد گری

نمایش کدهای دودویی که بعد از فرانک گری (Frank Gray) به نام **کد گِرِی** شناخته شد، یک سیستم از اعداد دودویی است که هر دو عدد متوالی فقط در یک بیت با هم اختلاف داشته باشند.
امروزه کدگری به طورِ گسترده برای تصحیحِ اشکالات در سیستم ارتباط دیجیتالی مثل تلویزیون کابلی و تلویزیون دیجیتال استفاده می‌شود.

## نام
یکی از محققان آزمایشگاه بل (Bell) به نام فرانک گری اولین بار به‌طور رسمی کد گری را مورد استفاده قرار داد و این کد بعد از گری توسط افرادی که از آن استفاده می‌کردند کد گری نامگذاری شد.

## تاریخچه و کاربردهای علمی
کد گری قبل از آن که در مهندسی به کار رود در پازل‌های ریاضی به کار برده می‌شد، ریاضیدان فرانسوی *Emile Boudat* از کد گری در سال ۱۸۷۸در تلگراف استفاده کرد و برای این کارش مدال دریافت کرد.

و اما کاربردهای آن، از کد گری به عنوان یک رمزگذار استفاده می‌شود که نسبت به رمزگذار عادی برتری دارد.

در نمایش کد گری خاصیت دایره‌ای بودن آن باعث می‌شود که دو عدد دو سر نیز فقط در یک بیت متفاوت باشند.

کد گری یک دور همیلتونی در یک مکعب n بعدی Q_n تولید می‌کند که هر کدام از اعداد آن یک راس را نشان می‌دهد و نیز در الگوریتم‌های ژنتیکی از آن استفاده می‌شود و البته برچسب گذاری جدول کارنو از موارد دیگر استفاده آن است.

زمانی کد گری برای آدرس دهی حافظه در کامپیوتر استفاده می‌شود، کامپیوتر نیروی کمتری صرف یافتن آدرس‌ها می‌کند چون هر آدرس با قبلی فقط در یک بیت متفاوت است.

طراحان مدارهای منطقی از کد گری به‌طور گسترده برای عبور چند بیت اطلاعات بین سیستم‌های همزمان استفاده می‌کنند.

یک دیسک کدبندی با یک کد خاکستری بازتابنده ۳ بیتی

## انگیزهٔ پیدایش کد گری
بعضی از دستگاه‌ها وضعیت دستگاه را با کدهای باینری نمایش می‌دهند، اگر این دستگاه‌ها از کد باینری عادی استفاده کند این دو وضعیت پشت سر هم خواهند بود
..

۰۱۱

۱۰۰...

و مشکل کد باینری عادی این است که در حالت طبیعی خیلی بعید است که چند بیت همزمان تغییر کنند همان‌طور که در بالا نمایش داده شده‌است که در کد باینری عادی هر سه بیت همزمان تغییر کرده‌اند اما می‌توان اعداد را طوری در کنار هم قرار داد که فقط در یک بیت متفاوت باشند و تغییر زیادی نکنند مثل011-001-101-100
پس کد باینری منعکس شده یا همان کد گری این مشکل را حل می‌کند زیرا که فقط یک بیت در آن‌ها تغییر می‌کند.
 Gray Binary
۰ ۰۰۰ ۰۰۰
۱ ۰۰۱ ۰۰۱
۲ ۰۱۱ ۰۱۰
۳ ۰۱۰ ۰۱۱
۴ ۱۱۰ ۱۰۰
۵ ۱۱۱ ۱۰۱
۶ ۱۰۱ ۱۱۰
۷ ۱۰۰ ۱۱۱

با توجه به حالت ۷ و ۰ می‌بینیم که فقط در یک بیت تفاوت دارند که همان خاصیت دوره‌ای یا چرخشی بودن کد گری می‌گوییم.

## ساختن کد گری <math>n</math> بیتی
یک کد گری n بیتی را می‌توان به صورت بازگشتی تولید کرد، به این شکل که یک لیست n-1 بیتی داریم آن را وارونه می‌کنیم (خط افقی در شکل زیر مانند آینه عمل کند) و در انتهای لیست اصلی می‌چسبانیم و سپس در ابتدای لیست اول 0 و در ابتدای لیست دوم 1 قرار می‌دهیم مثلاً برای کد گری یک بیتی ، G={0,1} را داریم (البته می‌توان از کد گری 0 بیتی هم استفاده کرد). n=0 ,G={0,1}، و بعد با آن کد گری1 بیتی را به صورت بازگشتی بسازیم و اکنون شبه کد آن را داریم.
بندانگشتی|چپ|400px|نمودار تولید یک کد خاکستری. ساخته Derrick Coetzee در Illustrator و فتوشاپ.

### الگوریتم کد گری
ابتدا یک الگوریتم برای تبدیل کد باینری عادی به کد گری وجود دارد.

۱ Let B[n:0] be the input array of bits in the usual binary representation, [0] being LSB
۲ Let G[n:0] be the output array of bits in Gray code
۳ G[n] = B[n]
۴ for i = n-1 downto 0
۵ G[i] = B[i+1] XOR B[i]

### الگوریتم تبدیل کد گری به کد باینری

۱ Let G[n:0] be the input array of bits in Gray code
۲ Let B[n:0] be the output array of bits in the usual binary representation
۳ B[n] = G[n]
۴ for i = n-1 downto 0
۵ B[i] = B[i+1] XOR G[i]

### الگوریتم تبدیل کد باینری به گری
اول از همه کد باینری عدد مورد نظر را می‌نویسیم

سپس از سمت چپ شروع می‌کنیم و اولین عدد را همان‌طور که هست نوشته سپس دوتا دوتا عددها رو مقایسه می‌کنیم، اگر هردو یکسان باشند در این صورت به جای آن دو عدد صفر می‌گذاریم، در غیر این صورت: یعنی اگر یکی از عددها صفر و دیگری یک باشد، آن وقت به جای آن دو عدد یک را به جای آنها می‌نویسیم

برای مثال

۷ باینری>> ۱ ۱ ۱ ۰

۷ گری>> ۰ ۰ ۱ ۰

#### یک الگوریتم سریع درC/java به شکل زیر است

۱ long inverseGray(long n) {
۲ long ish, ans, idiv;
۳ ish = ۱;
۴ ans = n;
۵ while(true) {
۶ idiv = ans>> ish;
۷ ans ^= idiv;
۸ if (idiv = n[i]) || (j <۰)) {
u[i] = -u[i];
i++;
j = g[i] + u[i];
}
g[i] = j;
}

اما یادآور می‌شویم که کد گری (n,k)تایی برای nهای فرد خاصیت چرخشی را حفظ نمی‌کنند ولی برای nهای زوج خاصیت چرخشی را حفظ می‌کنند.

## پیوند بیشتر

* "Gray Code" demonstration by Michael Schreiber, The Wolfram Demonstrations Project (with Mathematica implementation). 2007.
* NIST Dictionary of Algorithms and Data Structures: Gray code
* Numerical Recipes in C, section 20.2 describing Gray codes in detail
* Single-Track Circuit Codes by Hiltgen, Alain P.; Paterson, Kenneth G. 

## منابع

* Black, Paul E. Gray code. 25 February 2004. NIST
* Savage, Carla. "A Survey of Combinatorial Gray Codes." Society of Industrial and Applied Mathematics Review 39 (1997): 605–629.
* Wilf, Herbert S. Combinatorial algorithms: an update, SIAM, 1989, . Chapters 1-3.
* A Gray code implementation in Java to convert decimals

* Subsets or Combinations Can generate BRGC strings

رده:انتقال داده
رده:دستگاه‌های شمارش ارزش مکانی غیراستاندارد
رده:دستگاه‌های شمارش
رده:علوم رایانه
رده:محاسبه اعداد دودویی