কম্পিউটার টিউটোরিয়াল

রুবিতে বিটওয়াইজ অপারেশন মাস্টার করুন: টিপস অ্যান্ড ট্রিকস

সম্ভবত আপনার ডেইলি জবে বিটওয়াইজ ম্যাথ করার প্রয়োজন হয় না। রুবির বিটওয়াইজ AND এবং OR অপারেটর (`&` এবং `|`) কোনো উদ্দেশ্যে চেয়ে আরও অকস্মাত ব্যবহার হয়। কে `&&` বোঝাতে `&` টাইপ করেনি?

কিন্তু আপনি যদি C বা অ্যাসেম্বলার মতো নিম্নস্তরের ল্যাঙ্গুয়েজে প্রোগ্রামিং শিখেছেন, অথবা আমার মত Turbo Pascal-এ, তবে আপনি কমপক্ষে কিছু বিট টুইডলিং করেছেন থাকেন।

বিটওয়াইজ সমাধান কুল। যদি আপনি কম্পিউটারের সবচেয়ে বেসিক অপারেশন (বাইনারি ম্যাথ) ব্যবহার করে কোনো সমস্যা সমাধান করতে পারেন, তবে তার চেয়ে ইলিগ্যান্ট কিছু নেই।

রুবিতে বাইনারি সহ কাজ করা

আপনি জানেন কম্পিউটারে সব কিছু সংখ্যা হিসেবে রিপ্রেজেন্ট করা হয়, এবং সেগুলো বাইনারি ফরম্যাটে থাকে। কিন্তু রুবিতে তা কেমন দেখায়? এই উদাহরণে, আমি রুবি ব্যবহার করছি 'a' অক্ষরের ASCII কোড লুকআপ করার জন্য, তারপর এটি "বাইনারি" হিসেবে প্রিন্ট করছি।

রুবিতে বিটওয়াইজ অপারেশন মাস্টার করুন: টিপস অ্যান্ড ট্রিকস রুবিতে `ord` মেথড ব্যবহার করে ক্যারেক্টারের ASCII কোড পাওয়া যায়, এবং `printf` দিয়ে এর "বাইনারি" রিপ্রেজেন্টেশন প্রিন্ট করা যায়।

যদিও বাইনারি দেখাতে `printf` এর মত মেথড ব্যবহার করতে হয়, কিন্তু সেটি সবসময় বাইনারি থেকেই ছিল। আপনি আপনার রুবি কোডের ভেতরেই `0b11111111` সিন্ট্যাক্স দিয়ে বাইনারি নম্বর লিখতে পারেন।

রুবিতে বিটওয়াইজ অপারেশন মাস্টার করুন: টিপস অ্যান্ড ট্রিকস বাইনারি লিটারেল কোডে যোগ করতে 0b প্রিফিক্স দিয়ে দিন। যেমন `0b11111111`

বাইনারি ভ্যালু ম্যানিপুলেট করা

এখন আমরা জানি রুবিতে বাইনারি লিটারেল কীভাবে ব্যবহার করতে হয়, আমরা সেগুলো নিয়ে খেলতে পারি। তার জন্য আমরা বিটওয়াইজ অপারেটর ব্যবহার করব।

আপনি সম্ভবত বুলিয়ান অপারেটর `&&` নিয়ে কমফরটেবল। এক্সপ্রেশন `a && b` শুধু তখন true রিটার্ন করে যখন a এবং b দুটোই true। বিটওয়াইজ অপারেটরগুলো খুব সিমিলার।

উদাহরণস্বরূপ, বিটওয়াইজ AND দুটি ভ্যালু নেয় এবং সেগুলোকে বিট বাই বিট কমপেয়ার করে। যদি দুটি বিটই 1 হয়, তবে আউটপुटের কেরেসপন্ডিং বিট 1 সেট করে। না হলে 0 সেট করে। তাই আট বিট থাকলে আটটি আলাদা AND হবে। এক বিট থাকলে একটা AND। নিচের উদাহরণগুলো এক বিট ব্যবহার করে ইলাস্ট্রেট করেছে।

রুবিতে বিটওয়াইজ অপারেশন মাস্টার করুন: টিপস অ্যান্ড ট্রিকস এক বিটের সাথে বিটওয়াইজ AND অপারেশন উদাহরণ।

দুই বিটের জন্যও একইভাবে কাজ করে।

রুবিতে বিটওয়াইজ অপারেশন মাস্টার করুন: টিপস অ্যান্ড ট্রিকস প্রতিটি বিটের জোড়া আলাদা করে AND করা হয়

রুবির বিটওয়াইজ অপারেটর

প্রায় সব প্রোগ্রামিং ল্যাঙ্গুয়েজে এই বিটওয়াইজ অপারেটর সেট থাকে। আপনি যদি এদের সাথে পরিচিত না হন, তবে IRB-এ কিছু সময় বিতান এবং ট্রাই করুন। একবার শিখলে জীবনভর ব্যবহার করতে পারবেন।

অপারেটর বিবরণ উদাহরণ

& বিটওয়াইজ AND অপারেটর দুই ইনপুট ভ্যালুতে বিট 1 থাকলে রেজাল্টের বিট 1 সেট করে 0b1010 & 0b0111 == 0b0010
| বিটওয়াইজ OR অপারেটর যেকোনো একটি ইনপুট ভ্যালুতে বিট 1 থাকলে রেজাল্টের বিট 1 সেট করে 0b1010 | 0b0111 == 0b1111
^ বিটওয়াইজ XOR অপারেটর যেকোনো একটি ইনপুটে বিট 1 থাকলে কিন্তু দুটোই না থাকলে রেজাল্ট বিট 1 সেট করে 0b1010 | 0b0111== 0b1101
~ বিটওয়াইজ ইনভার্স অপারেটর ইনপুট 1 হলে রেজাল্ট বিট 0 এবং বিপরীতভাবে সেট করে ~0b1010 == 0b0101
<< বিটওয়াইজ লेफট শিফট অপারেটর. ইনপুট বিটগুলো নির্দিষ্ট সংখ্যক প্লেস লेफটে সরিয়ে দেয়। 0b1010 << 4== 0b10100000
>> বিটওয়াইজ রাইট শিফট অপারেটর. ইনপুট বিটগুলো নির্দিষ্ট সংখ্যক প্লেস রাইটে সরিয়ে দেয় 0b1010 >> 4 == 0b0000

ব্যবহারিক ব্যবহার: কনফিগারেশন ফ্ল্যাগ

ঠিক আছে, বিটওয়াইজ ম্যাথের এটি সবচেয়ে বোরিং ব্যবহার। কিন্তু এটি সবচেয়ে কমন ব্যবহারও। যদি আপনি Java বা C বা C++-এ লেখা কোডের সাথে ইন্টারফেস করেন, তবে বিটওয়াইজ কনফিগারেশন ফ্ল্যাগের সাথে আপনার saamna হবে।

কল্পনা করুন ১৯৯৬ এবং আপনি স্ক্র্যাচ থেকে একটি ডেটাবেস সিস্টেম বানিয়েছেন। Hackers সিনেমা দেখে আপনি মনে করেন এক্সেস কন্ট্রোল বিল্ট-ইন রাখা ভালো।

আপনার DB-এ ইউজার ৮টি অ্যাকশন নিতে পারে: রিড, রাইট, ডিলিট, এবং আরও পাঁচটি। আপনি প্রতিটা স্বতন্ত্রভাবে সেট করতে চান। এমন ইউজার থাকতে পারে যারা রিড করতে পারে কিন্তু রাইট বা ডিলিট করতে পারে না। আবার কেউ রাইট করতে পারে কিন্তু টেবিল ড্রপ করতে পারে না।

এই কনফিগারেশন ফ্ল্যাগগুলো স্টোর করার সবচেয়ে ইফিশিয়েন্ট উপায় হলো একটি সিঙ্গেল বাইটের বিট হিসেবে। তারপর ইউজার সিম্পলি OR করবে যেকোনো কম্বিনেশন তৈরি করতে।

MYDB_READ = 0b00000001 # এগুলোকে বিটমাস্ক বলা হয় MYDB_WRITE = 0b00000010 MYDB_DELETE = 0b00000100 MYDB_INDEX = 0b00001000 user.permissions = MYDB_READ | MYDB_WRITE 

বleid, এটি ইউনিক্স ফাইল পারমিশন হ্যান্ডল করার মতো। আপনি কখনো কেন মэдিক নম্বর ব্যবহার করতে হয় ফাইল রিড-অনলি করার জন্য, এখন জানেন।

বিটে কনফিগারেশন অপশন স্টোর করলেই হবে না, কোনো নির্দিষ্ট বিট সেট আছে কিনা ডিটেক্ট করতে পারা লাগবে। তার জন্য বিটওয়াইজ AND ব্যবহার করুন।

রুবিতে বিটওয়াইজ অপারেশন মাস্টার করুন: টিপস অ্যান্ড ট্রিকস বিটমাস্কের সাথে AND ব্যবহার করে বিট সেট আছে কিনা নির্ণয় করুন।

কম ব্যবহারিক ব্যবহার (যদি আপনি C প্রোগ্রামার না হন)

এখন কিছু ম্যাথ-ম্যাজিক্যাল জিনিস করি।

ঐতিহাসিকভাবে, বিট ম্যানিপুলেশন ব্যবহার হতো যখন আপনি কোনো কম্পিউটেশনের লাস্ট ফ্র্যাকশন মিলিসেকেন্ড নিচুড়তে চেয়েছিলেন। তাই গ্রাফিক্স প্রোগ্রামাররা এবং যারা পারফরম্যান্স চেয়েছিলেন তারা এটা ব্যাপকভাবে ব্যবহার করত।

এই টেকনিকগুলো প্রতিদিনের রুবি ডেভেলপমেন্টের জন্য প্র্যাকটিক্যাল নয়। কিন্তু লার্নিং এক্সারসাইজ হিসেবে মজার, এবং এমবেডেড সিস্টেম প্রোগ্রামিং-এ আসলে উপকারী হতে পারে। আরও বিস্তারিত জানতে এই বিট টুইডলিং হ্যাকস লিস্ট দেখুন।

দুই গুন করা বা ভাগ করা পাওয়ার অফ টু দিয়ে

১, ২, ৪, এবং ৮ এর বাইনারি রিপ্রেজেন্টেশন দেখুন। আপনি দেখবেন, সংখ্যা ডাবল করা সমান সব বিট এক প্লেস লेफট শিফট করা। এবার হাফ করা সমান রাইট শিফট।

রুবিতে বিটওয়াইজ অপারেশন মাস্টার করুন: টিপস অ্যান্ড ট্রিকস ১, ২, ৪, ৮ এর বাইনারি রিপ্রেজেন্টেশন

আপনি মনে করবেন, আমাদের শিফট-লेफট এবং শিফট-রাইট অপারেটর আছে। অর্থাৎ আমরা শুধু বিট শিফট করেই পাওয়ার অফ টু দিয়ে গুন বা ভাগ করতে পারি।

রুবিতে বিটওয়াইজ অপারেশন মাস্টার করুন: টিপস অ্যান্ড ট্রিকস বিটওয়াইজ শিফট অপারেটর দিয়ে পাওয়ার অফ টু দিয়ে গুন বা ভাগ করা যায়

দুই পজিটিভ ইন্টিজারের গড়

দুই ইন্টিজার যোগ করা যায়: (x+y) == (x&y)+(x|y) == (x^y)+2*(x&y)। গড় বের করতে হলে শুধু দুই দিয়ে ভাগ, যা রাইট শিফট অপারেটর দিয়ে পাওয়া যায়।

রুবিতে বিটওয়াইজ অপারেশন মাস্টার করুন: টিপস অ্যান্ড ট্রিকস দুটি পজিটিভ ইন্টিজারের গড়: (x&y)+((x^y)>>1)

ফাস্ট ইনভার্স স্কোয়ার রুট

বিট টুইডলিং ব্লগ পোস্টে জন কার্ম্যাকের ফাস্ট ইনভার্স স্কোয়ার রুট অ্যাপ্রক্সিমেশন ছাড়া अधूরা। ১৯৯৯ সালের Quake 3 Arena সোর্স কোড থেকে। অ্যালগরিদম তার নয়, কিন্তু সবচেয়ে বিখ্যাত ইমপ্লিমেন্টেশন তারই।

আমি সরাসরি রুবিতে পোর্ট করার চেষ্টা করব না, কারণ এটি ফ্লোটিং পয়েন্ট নম্বরের বাইনারি রিপ্রেজেন্টেশন কনস্ট্রাক্ট করে এমনভাবে যা C-থেকে রুবিতে ডাইরেক্টলি ট্রান্সলেট করা যায় না।

float Q_rsqrt( float number ) { long i; float x2, y; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * ( long * ) &y; // evil floating point bit level hacking i = 0x5f3759df - ( i >> 1 ); // what the fuck? y = * ( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed return y; } 
  1. রুবিতে ল্যাম্বডা মাস্টার করুন: বেসিক থেকে অ্যাডভান্সড টেকনিক

  2. রুবি ২.৬-এ ৯টি গুরুত্বপূর্ণ উন্নতির অন্বেষণ

  3. রুবিতে ডেটা ইনস্পেকশন মাস্টার করুন: রেইলস ডেভেলপারদের জন্য ডিবাগিং টেকনিক

  4. রুবি ২.১-এ আপগ্রেড: ১৫-২০% দ্রুত সার্ভার রেসপন্স এবং নِয়ার-জিরো GC টাইম