প্রোগ্রামিং C বাইনারি সংখ্যা


বাইনারি সংখ্যা।


আমরা তো দৈনন্দিন জীবনে নানা হিসাব-নিকাশের জন্য দশভিত্তিক (decimal) সংখ্যা পদ্ধতি ব্যবহার করি। কিন্তু কম্পিউটার ব্যবহার করে দুইভিত্তিক বা বাইনারি (binary) সংখ্যা পদ্ধতি। দশভিত্তিক সংখ্যা পদ্ধতিতে আছে মোট দশটি অঙ্ক 0, 1, 2, 3, 4, 5, 6, 7, 8, 9আর বাইনারিতে দুটি, 0 আর 1। আমরা এই অধ্যায়ে বাইনারি সংখ্যা পদ্ধতির কিছু মৌলিক জিনিস দেখব আর বাইনারি থেকে ডেসিমাল এবং ডেসিমাল থেকে বাইনারি সংখ্যায় রূপান্তর করা শিখব। ডেসিমালে আমরা গণনা করি এভাবে: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, … 19, 20, 21, …, 98, 99, 100, 101 ...। দেখোযখনই আমরা ডান দিকের ঘরে (এককের ঘরেদশটি অঙ্ক ব্যবহার করে ফেলিতখন তার বাঁয়ে দশকের ঘরের অঙ্কের মান এক বাড়াই (আর যদি না থাকে তাহলে বসাই বা 0-এর সঙ্গে যোগ করি আর কিকারণ আর 09 কিন্তু একই কথাতাই 09-এর পরবর্তি সংখ্যা হচ্ছে 10), আবার দশকের ঘরে থেকে সব অঙ্ক ব্যবহার করে ফেলার পরে শতকের ঘরের অঙ্কের মান এক বাড়াই (আর যদি না থাকে তাহলে বসাই বা 0-এর সঙ্গে যোগ করি আর কি)। তেমনই বাইনারিতে আমরা গণনা করব এইভাবে: 0, 1, 10, 11, 100, 101, 110, 111, 1000, 1001, 1010, 1011 ...। যেহেতু অঙ্ক মাত্র দুটি,তাই দুটি অঙ্কের ব্যবহার হয়ে গেলেই বাঁ দিকের ঘরে এক বসাতে হয় বা 0-এর সঙ্গে যোগ করতে হয় (বাঁ দিকে তো আমরা ইচ্ছামত শূন্য বসাতে পারি)

বাইনারি সিস্টেমে অবশ্য আমরা এককের ঘরদশকের ঘরশতকের ঘরসহস্রের ঘর না বলে বলব একের ঘরদুইয়ের ঘরচারের ঘর,আটের ঘর। কেন বল তোএকটু চিন্তা করো।

ডেসিমালে যেমন 10 লিখতে দুটি অঙ্ক লাগে, 100 লিখতে তিনটি, 1000 লিখতে চারটিতেমনই বাইনারিতে দুই লিখতে দুটি (10), চার লিখতে তিনটি (100), আট লিখতে চারটি (1000), ষোল লিখতে পাঁচটি (10000) অঙ্ক ব্যবহার করতে হয়। ডেসিমালে ডান দিকের প্রথম অঙ্ক (10= 1) হচ্ছে এককের ঘরদ্বিতীয় অঙ্ক (101 = 10) হচ্ছে দশকের ঘরতৃতীয় অঙ্ক (102 = 100) হচ্ছে শতকের ঘর,তেমনই বাইনারিতে ডানদিকের প্রথম অঙ্ক (20 = 1) হচ্ছে একের ঘরপরের অঙ্ক (2= 2) হচ্ছে দুইয়ের ঘরতারপর (2= 4) হচ্ছে চারের ঘরএই রকম।
দশভিত্তিক সংখ্যায় যেমন যোগবিয়োগগুণভাগ করা যায়তেমনই বাইনারিতে করা যায়। আসলে যোগ করতে পারলে কিন্তু বাকি কাজ করা কোনো ব্যাপার নয়। আবার বাইনারিতে ভগ্নাংশের ব্যাপার আছেতবে আমি কেবল পূর্ণসংখ্যা নিয়েই আলোচনা করব।

যোগের ক্ষেত্রে মূল হিসাবগুলো হচ্ছে:
0 + 0 = 0,
0 + 1 = 1,
1 + 0 = 1,
1 + 1 = 10

ডেসিমালের মতোই হিসাব, 1 + 1 এর ক্ষেত্রে দেখোদুইয়ের (10) শূন্য এল প্রথমেহাতে থাকে একসেটি পরে লিখলাম।
101 + 101 = কত?
প্রথমে একের ঘরের যোগ, 1 + 1 = 10। তাই যোগফলের একের ঘরে বসবে আর হাতে থাকল 1 (carry)। এবারে দুইয়ের ঘরে, 0 + 0 = 0, এখন এই 0-এর সঙ্গে হাতের যোগ করতে হবে। তাহলে যোগফলের দুইয়ের ঘরে বসবে 1। এবারে চারের ঘরের যোগ করলে পাই, 1 + 1 = 10। হাতে কিছু নেই (কোনো carry নেই)। সুতরাং চারের ঘরে বসবে আর বসবে আটের ঘরে। যোগফল: 1010। এবারে বলো 1011 + 1011 = কতযোগ করে যদি দেখো যোগফল 10110 হয়নিতাহলে তুমি যোগে কোথাও ভুল করেছ।

বিয়োগের ক্ষেত্রেও ডেসিমালের মতো হিসাব হবে।
0 – 0 = 0,
1 – 0 = 1,
1 – 1 = 0,
0 – 1 = 1

শেষেরটি খেয়াল করো, 23 – 15 করার সময় আমরা কী করিতখন 3-এর বাঁয়ে একটি কাল্পনিক ধরে নিই (বা ধার করি),তারপর 13 – 5 = 8 লেখি। আর যেই একটি ধার করলামসেটি পরের ঘরে 1-এর সঙ্গে যোগ করে দিই। তেমনই বাইনারিতে 0 – 1করতে গেলে 0-এর বাঁয়ে একটি এক ধরবতখন সংখ্যাটি হবে 10 (দুই), এই দুই থেকে এক বাদ দিলে এক থাকবে। পরের ঘরে একটি এক যোগ করতে হবে (যেই সংখ্যাটি বিয়োগ হচ্ছে তার সঙ্গে)
110 – 101 = কত?

একের ঘরে থেকে বাদ দিলে থাকে 1, এখানে ধার করতে হয়েছে। তাই 101-এর দুইয়ের ঘরে সেটি যোগ করে দেব। তাহলে দুইয়ের ঘরে 1 – 1 = 0, চারের ঘরে 1 – 1 = 0। তাই বিয়োগফল হবে: 001 বা 1। যোগ-বিয়োগ পারলে গুণ-ভাগ না পারার কারণ নেই। ডেসিমালের মতোই নিয়ম।

আবার কোনো ডেসিমাল সংখ্যাকে আমরা নির্দিষ্ট অঙ্ক x 10ওই অঙ্কের অবস্থান-এর যোগফল হিসেবে যেমন লিখতে পারিবাইনারি সংখ্যাকেও নির্দিষ্ট অঙ্ক x 2ওই অঙ্কের অবস্থান-এর যোগফল হিসেবে লেখা যায়। যেমন: 1903 = 1 x 10+ 9 x 102 + 0 x 101 + 3 x 100
বাইনারি: 10110 = 1 x 24 + 0 x 23 + 1 x 22 + 1 x 21 + 0 x 20। ইংরেজিতে একে বলে Exponential Expression

এখন কোনো বাইনারি সংখ্যার মান যদি ডেসিমালে বের করতে চাইতবে প্রথমে বাইনারি সংখ্যাটিকে এক্সপোনেনশিয়াল এক্সপ্রেশন আকারে লিখতে হবে। তারপর গুণফলগুলো ডেসিমালে হিসাব করতে হবে। নিচের উদাহরণটি দেখো:

10110 = 1 x 24 + 0 x 23 + 1 x 22 + 1 x 21 + 0 x 2= 1 x 16 + 0 x 8 + 1 x 4 + 1 x 2 + 0 x 1
= 16 + 0 + 4 + 2 + 0 = 22

অর্থাৎ বাইনারি 10110 = ডেসিমাল 22। আমরা অনেকক্ষণ কোনো প্রোগ্রামিং করছি নাচলো বাইনারি সংখ্যার ডেসিমাল মান বের করার একটি প্রোগ্রাম লিখে ফেলি। পদ্ধতি তো জানা হয়ে গেছে। এখন গুরুত্বপূর্ণ প্রশ্ন হচ্ছেবাইনারি সংখ্যা রিড করব কী দিয়েআমরা স্ট্রিং ব্যবহার করতে পারি।

char binary[] = "10110";

int len = 5; // স্ট্রিংয়ের দৈর্ঘ্য 5
int decimal = 0; // এখনো কোনো হিসাব করিনিতাই ধরলাম ডেসিমাল মান 0

এবারে আমরা একটি লুপের সাহায্যে বাইনারি সংখ্যার প্রতিটি অঙ্কের সঙ্গে 2ওই অঙ্কের অবস্থান গুণ করে সেটি ডেসিমালের সঙ্গে যোগ করে দেব। প্রথম ক্যারেক্টার অর্থাৎ binary[0]তে তো '1' আছে,-এর অবস্থান কত বলো তো?-এর অবস্থান হচ্ছে 4। তারপরের অঙ্কের বেলায় অবস্থানের মান এক কমবেএভাবে একেবারে শেষের অঙ্কের বেলায় অবস্থান হবে 0
   int position = 4;  
   int indx;  
   for(indx = 0; indx < len; indx++) {  
       decimal = decimal + pow(2, position);  
       position--;  
   }  

লুপ থেকে বের হলে আমরা সম্পূর্ণ বাইনারি সংখ্যার ডেসিমাল মান পেয়ে যাব। এখানে দেখোআমি pow ফাংশন ব্যবহার করেছি। এটির কাজ বলা আছে math.h হেডার ফাইলে। ab-এর মান বের করার জন্য pow(a, b) বলে দিলেই হয়। তাহলে আমাদের পুরো প্রোগ্রামটি দাঁড়াচ্ছে এই রকম:
 #include <stdio.h>  
 #include <string.h>  
 #include <math.h>  
 int main()   
 {  
     char binary[65];  
     int len, decimal, power, i;  
     printf("Enter the binary number: ");  
     scanf("%s", binary);  
     decimal = 0;  
     len = strlen(binary);  
     power = len - 1;  
     for(i = 0; i < len; i++) {  
         decimal += pow(2, power);  
         power--;  
     }  
     printf("Decimal value is %d\n", decimal);  
     return 0;  
 }  
 প্রোগ্রাম: ১২.১  

প্রোগ্রাম কম্পাইল করে রান করো। ইনপুট যদি 10110 দাওতাহলে আউটপুট কত আসেআউটপুট আসে 31 কিন্তু আউটপুট তো আসা উচিত 22। তাহলে আমরা কোথাও ভুল করেছি। তোমরা নিজে নিজে ভুলটি বের করার চেষ্টা করো।

আমাদের তো আসলে pow(2, position)কে বাইনারি সংখ্যার ওই position-এর অঙ্কটি দিয়ে গুণ করার কথাসেটি আমরা করতে ভুলে গেছি। অর্থাৎ আমাদের লিখতে হবে:

decimal += binary[i] * pow(2, power);

একটি ব্যাপার খেয়াল করছো তো? 10110-এর একের ঘরের অঙ্কটি আমাদের অ্যারের শেষ ক্যারেক্টারআর ষোলোর ঘরের অঙ্কটি হচ্ছে অ্যারের প্রথম ক্যারেক্টার। অ্যারেতে সংখ্যাটি আছে এইভাবে: ['1', '0', '1', '1', '0']। তাই binary[0]-এর সঙ্গে গুণ হবে pow(2, 4), binary[1]-এর সঙ্গে গুণ হবে pow(2, 3), …, এভাবে binary[4]-এর সঙ্গে গুণ হবে pow(2, 0)। এখন প্রোগ্রামটি ঠিক করে নিয়ে তারপর চালাও। ইনপুট 10110-এর জন্য কী আউটপুট?

আমি তো আউটপুট দেখতে পাচ্ছি Decimal value is 1510। ভুলটি কোথায় হলোসব তো ঠিকই করলাম। তোমরা আবার বিরক্ত হয়ে যাচ্ছ না তোটেস্ট ক্রিকেট খেলার সময় যেমন ধৈর্যের প্রয়োজনপ্রোগ্রামিংও তেমনই ধৈর্যের খেলা।

ভুলটি যে decimal += binary[i] * pow(2, power); স্টেটমেন্টে হয়েছে তাতে কোনো সন্দেহ নেই। কারণ আমরা এখানেই একটু পরিবর্তন করেছি। লক্ষ করো, binary[i]-এর মান হয় '0' বা '1' (মানে ক্যারেক্টার '0' বা ক্যারেক্টার '1')। এখন কম্পিউটার '0' বলতে বোঝে 48 আর '1' বলতে বোঝে 49। ঝামেলাটা এখানেই হয়েছে। এখন এই '0'কে আর '1'কে বোঝাব কীভাবে?

'0' – '0' = 48 – 48 = 0
'1' – '0' = 49 – 48 = 1

বুদ্ধিটা দারুণ নাআমরা binary[i] না লিখে (binary[i] – '0') লিখলেই ঝামেলা শেষ। এবারে প্রোগ্রাম ঠিকঠাক কাজ করবে (যদি না তুমি নতুন কোনো ভুল করে থাকো)

এবারে আমরা দেখব ডেসিমাল থেকে বাইনারিতে রূপান্তর। একটি উদাহরণের সাহায্যে পদ্ধতিটা দেখাই। ধরো 95কে বাইনারিতে রূপান্তর করতে হবে। এখন আমাদের বের করতে হবে n-এর সর্বোচ্চ মানযেখানে 2n <= 95। দুইয়ের পাওয়ারগুলো হচ্ছে 1, 2, 4, 8, 16, 32, 64, 128, ...। এখানে আমরা দেখতে পাচ্ছি 64 < 95 বা 2< 95। তাহলে n-এর মান 6। আর আমাদের বাইনারি সংখ্যাটি হবে সাত অঙ্কের (0 থেকে মোট সাতটি অঙ্ক)। যেহেতু 64 < 95, তাই এই সংখ্যাটি নেওয়া যায়। তাহলে চৌষট্টির ঘরে (বাঁ থেকে প্রথম বা ডান থেকে সপ্তমহবে 1 (1xxxxxx)। এখন n-এর মান কমাই। 64 + 25 = 64 + 32 = 96, যা কিনা 95-এর চেয়ে বড়। তাই একে নেওয়া যাবে না। অতএব বত্রিশের ঘরে বসাই (10xxxxx)। এবারে n-এর মান আবার এক কমাই, n-এর মান এখন 4। 64 + 24 = 64 + 16 = 80 < 95। সুতরাং ষোলোর ঘরে হবে 1 (101xxxx)। এখন n-এর মান এক কমাই, n = 3। 80 + 23 = 80 + 8 = 88 < 95। তাই আটের ঘরেও বসবে (1011xxx)। এরপর একইভাবে, n = 2-এর জন্য 88 + 22 = 88 + 4 = 92 < 95। চারের ঘরেও বসবে(10111xx)। তারপর n = 1, 92 + 21 = 92 + 2 = 94 < 95। দুইয়ের ঘরেও 1 (101111x)। এখন n = 0, 94 + 20 = 94 + 1 = 95। তাই একের ঘরেও 1। সুতরাং বাইনারি সংখ্যাটি হচ্ছে 1011111। তোমরা এখন এই পদ্ধতিতে কোনো দশভিত্তিক সংখ্যাকে বাইনারিতে রূপান্তর করার প্রোগ্রাম লিখে ফেলো এবং বিভিন্ন মান দিয়ে পরীক্ষা করে দেখো।

এখন একই কাজ আমরা একটু অন্যভাবে করব। নিচের টেবিলটি দেখো:


ভাগফল
ভাগশেষ
95/ 2
47
1
47/2
23
1
23/2
11
1
11/2
5
1
5/2
2
1
2/2
1
0
1 /2
0
1

এবারে ভাগশেষ কলামের অঙ্কগুলো শেষ থেকে প্রথম ক্রমে লেখলেই আমরা বাইনারি নম্বরটা পেয়ে যাব: 1011111। আর ভাগের কাজটি আমরা ততক্ষণ করব যতক্ষণ না ভাগফল পাচ্ছি।
এই পদ্ধতিতেও তোমরা ডেসিমাল থেকে বাইনারি রূপান্তরের জন্য একটি কোড লিখে ফেলো। রূপান্তরের কোডটি main ফাংশনে না করে আলাদা একটি ফাংশনে করবে।

No comments

Powered by Blogger.