সম্ভাবনা হল আপনার দিনের কাজে সাধারণত বিটওয়াইজ গণিত করার দরকার নেই। রুবির বিটওয়াইজ AND এবং OR অপারেটর ( &এবং | ) সম্ভবত উদ্দেশ্যের চেয়ে দুর্ঘটনাক্রমে বেশি ব্যবহৃত হয়। কে ভুলবশত টাইপ করেনি এবং কখন তারা মানে &&?
কিন্তু আপনি যদি সি বা অ্যাসেম্বলারের মতো নিম্ন স্তরের ল্যাঙ্গুয়েজ বা আমার ক্ষেত্রে টার্বো প্যাসকেল প্রোগ্রামিং করে বড় হয়ে থাকেন তাহলে আপনি সম্ভবত কিছুটা এলোমেলো করে ফেলেছেন।
সমস্যার বিটওয়াইজ সমাধানগুলি কেবল দুর্দান্ত। আপনি যদি কম্পিউটারে সক্ষম সবচেয়ে মৌলিক ক্রিয়াকলাপগুলি ব্যবহার করে আপনার সমস্যার সমাধান করতে সক্ষম হন (বাইনারী গণিত), এটি এর চেয়ে বেশি মার্জিত হয় না৷
রুবিতে বাইনারির সাথে কাজ করা
আপনি সম্ভবত জানেন যে আপনার কম্পিউটারের সবকিছুই সংখ্যা হিসাবে উপস্থাপন করা হয় এবং সেই সংখ্যাগুলি বাইনারি বিন্যাসে রয়েছে। কিন্তু যে রুবি মত দেখায় কি? এই উদাহরণে, আমি "a" অক্ষরের জন্য ASCII অক্ষর কোড খুঁজতে রুবি ব্যবহার করছি, তারপর "বাইনারী" হিসাবে মুদ্রণ করছি৷
আপনি ord
ব্যবহার করতে পারেন একটি চরিত্রের ASCII কোড পেতে রুবিতে পদ্ধতি, এবং তারপর printf
ব্যবহার করুন এটির একটি "বাইনারী" উপস্থাপনা প্রিন্ট করতে।
যদিও বাইনারিতে সংখ্যা প্রদর্শনের জন্য আমাদের printf এর মতো একটি পদ্ধতি ব্যবহার করতে হবে, এটি সর্বদা বাইনারি ছিল। আপনি 0b11111111
সিনট্যাক্স ব্যবহার করে আপনার রুবি কোডের ভিতরে বাইনারি সংখ্যা লিখতে পারেন .
আপনার কোডে বাইনারি লিটারেল যোগ করতে, 0b এর সাথে স্ট্রিং এবং শূন্যের উপসর্গ দিন। তাই 0b11111111
বাইনারি মান ম্যানিপুলেট করা
এখন যেহেতু আমরা রুবিতে বাইনারি লিটারাল ব্যবহার করতে জানি, আমরা তাদের সাথে খেলা শুরু করতে পারি। এটি করার জন্য আমরা বিটওয়াইজ অপারেটর ব্যবহার করব।
আপনি সম্ভবত &&এর মত বুলিয়ান অপারেটরদের সাথে স্বাচ্ছন্দ্য বোধ করছেন। a &&b অভিব্যক্তিটি সত্য দেখায় যদি a এবং b উভয়ই সত্য হয়। বিটওয়াইজ অপারেটরগুলি খুব একই রকম।
উদাহরণস্বরূপ, bitwise AND দুটি মান নেয় এবং বিট করে তাদের তুলনা করে। উভয় বিট 1 হলে, এটি সংশ্লিষ্ট আউটপুট বিটকে 1 এ সেট করে। যদি না হয়, এটি শূন্যে সেট করে। সুতরাং আপনার যদি আটটি বিট থাকে, তাহলে আপনার আটটি আলাদা AND ঘটবে। আপনার যদি এক বিট থাকে, তাহলে আপনার কাছে একটি AND আছে। নিম্নলিখিত উদাহরণগুলি একটি একক বিট ব্যবহার করে এটিকে চিত্রিত করে৷
৷বিটওয়াইজ এবং একটি একক বিটের সাথে অপারেশনের উদাহরণ।
এটি দুটি বিটের জন্য একই কাজ করে৷
৷বিটগুলির প্রতিটি জোড়া আলাদাভাবে এবং করা হয়
রুবির বিটওয়াইজ অপারেটর
প্রায় প্রতিটি প্রোগ্রামিং ভাষাই বিটওয়াইজ অপারেটরের এই সেটের সাথে আসে। আপনি যদি তাদের সাথে পরিচিত না হন তবে IRB-এ তাদের চেষ্টা করে দেখতে একটু সময় ব্যয় করুন। একবার আপনি সেগুলি শিখলে, আপনি সেগুলি আপনার বাকি জীবনের জন্য ব্যবহার করতে সক্ষম হবেন৷
& | বিটওয়াইজ এবং অপারেটর ফলাফলের বিটটিকে 1-এ সেট করে যদি এটি উভয় ইনপুট মানেই 1 হয় | 0b1010 & 0b0111 == 0b0010 |
| | বিটওয়াইজ বা অপারেটর ফলাফলের বিট 1-এ সেট করুন যদি ইনপুট মান 1 হয় | 0b1010 | 0b0111 == 0b1111 |
^ | Bitwise XOR অপারেটর ফলাফল বিটটিকে 1-এ সেট করে যদি এটি ইনপুট মানের মধ্যে 1 হয়, তবে উভয়ই নয় | 0b1010 | 0b0111== 0b1101 |
~ | বিটওয়াইজ ইনভার্স অপারেটর ইনপুট 1 হলে ফলাফল বিটকে 0 এ সেট করে এবং এর বিপরীতে | ~0b1010 == 0b0101 |
<< | বিটওয়াইজ বাম শিফট অপারেটর . ইনপুট বিটগুলিকে একটি নির্দিষ্ট সংখ্যক স্থানের বামে স্থানান্তর করে৷ | ৷ 0b1010 << 4== 0b10100000 |
>> | Bitwise Right Shift Operator . ইনপুট বিটগুলিকে একটি নির্দিষ্ট সংখ্যক স্থানের দ্বারা ডানদিকে সরান | 0b1010 >> 4 == 0b0000 |
ব্যবহারিক ব্যবহার:কনফিগারেশন ফ্ল্যাগ
ঠিক আছে, ঠিক আছে, এটি বিটওয়াইজ গণিতের সবচেয়ে বিরক্তিকর ব্যবহার হতে হবে। কিন্তু এটি সবচেয়ে সাধারণ এক. আপনি যদি কখনও জাভা বা C বা C++ এ লেখা কোডের সাথে ইন্টারফেস করতে চান তবে আপনি শেষ পর্যন্ত বিটওয়াইজ কনফিগারেশন ফ্ল্যাগগুলি দেখতে পাবেন।
কল্পনা করুন যে এটি 1996 এবং আপনি স্ক্র্যাচ থেকে একটি ডাটাবেস সিস্টেম তৈরি করেছেন। যেহেতু আপনি এইমাত্র হ্যাকারস মুভিটি দেখেছেন, তাই আপনি ভেবেছেন যে এটি কোনো ধরনের অ্যাক্সেস কন্ট্রোলে তৈরি করা ভালো হতে পারে।
একজন ব্যবহারকারী আপনার ডিবিতে 8টি অ্যাকশন নিতে পারে:পড়ুন, লিখুন, মুছুন এবং আরও পাঁচটি। আপনি স্বাধীনভাবে তাদের প্রতিটি সেট করতে সক্ষম হতে চান. আপনার এমন একজন ব্যবহারকারী থাকতে পারে যে পড়তে পারে কিন্তু লিখতে বা মুছতে পারে না। আপনার এমন একটি থাকতে পারে যা লিখতে পারে কিন্তু টেবিল ড্রপ করতে পারে না।
এই কনফিগারেশন ফ্ল্যাগগুলি সঞ্চয় করার সবচেয়ে কার্যকর উপায় হল একটি একক বাইটে বিট হিসাবে। তারপর একজন ব্যবহারকারী তাদের প্রয়োজনে অনুমতির যেকোন সমন্বয় তৈরি করতে তাদের একত্রে বা ব্যবহার করবে।
MYDB_READ = 0b00000001 # These numbers are called bitmasks
MYDB_WRITE = 0b00000010
MYDB_DELETE = 0b00000100
MYDB_INDEX = 0b00001000
user.permissions = MYDB_READ | MYDB_WRITE
যাইহোক, এটি ইউনিক্স ফাইলের অনুমতিগুলি কীভাবে পরিচালনা করা হয় তার অনুরূপ। আপনি যদি কখনও ভেবে থাকেন যে কেন আপনাকে শুধুমাত্র একটি ফাইল পড়ার জন্য একটি ম্যাজিক নম্বর ব্যবহার করতে হবে, এখন আপনি জানেন৷
বিটগুলিতে কনফিগারেশন বিকল্পগুলি সংরক্ষণ করা খুব কার্যকর হবে না যদি না আপনি একটি নির্দিষ্ট বিট সেট করা হয়েছে কিনা তা সনাক্ত করতে পারেন। এটি করার জন্য, আপনি শুধু একটি বিটওয়াইজ এবং ব্যবহার করুন।
একটি বিট সেট করা আছে কিনা তা নির্ধারণ করতে একটি বিটমাস্ক সহ AND ব্যবহার করুন৷
কম ব্যবহারিক ব্যবহার (যদি না আপনি একজন C প্রোগ্রামার না হন)
এখন কিছু গাণিতিক-জাদুকর জিনিস করা যাক।
ঐতিহাসিকভাবে, বিট ম্যানিপুলেশন ব্যবহার করা হয়েছিল যখন আপনি কিছু কম্পিউটেশনের মিলিসেকেন্ডের শেষ ভগ্নাংশটি চেপে দেওয়ার চেষ্টা করছেন। সুতরাং আপনি যেমন কল্পনা করতে পারেন, এটি গ্রাফিক্স প্রোগ্রামাররা এবং অন্যদের দ্বারা অনেক বেশি ব্যবহার করা হয়েছিল যাদের সবকিছুর উপরে পারফরম্যান্সের প্রয়োজন ছিল৷
তাই এই ধরনের কৌশল দৈনন্দিন রুবি বিকাশের জন্য ব্যবহারিক নয়। কিন্তু এগুলি এখনও একটি মজার শেখার ব্যায়াম, এবং আপনি যদি এমবেডেড সিস্টেম প্রোগ্রামিংয়ের মতো জিনিসগুলিতে যান তবে বৈধভাবে কার্যকর হতে পারে। আরও বিস্তৃত চিকিত্সার জন্য, বিট টুইডলিং হ্যাকগুলির এই তালিকাটি দেখুন।
দুইয়ের শক্তি দ্বারা গুণ ও ভাগ করা
আসুন 1, 2, 4, এবং 8 সংখ্যার বাইনারি উপস্থাপনা দেখি। আপনি দেখতে পাচ্ছেন, সংখ্যা দ্বিগুণ করা সমস্ত বিটকে এক জায়গায় বাম দিকে সরানোর সমতুল্য। একইভাবে, সংখ্যাকে অর্ধেক করা ডানদিকে সরানোর সমান।
1, 2, 4 8 এর বাইনারি উপস্থাপনা
আপনি যদি মনে করেন, আমাদের শিফট-লেফট এবং শিফট-ডান অপারেটর আছে। তার মানে আমরা বিট পরিবর্তন করে দুটির শক্তি দিয়ে গুণ ও ভাগ করতে পারি।
আপনি বিটওয়াইজ শিফ্ট অপারেটর ব্যবহার করতে পারেন দুইটির শক্তি দ্বারা গুণ বা ভাগ করতে
দুটি ধনাত্মক পূর্ণসংখ্যার গড়
আপনি দুটি পূর্ণসংখ্যার মৌলিক যোগ করতে পারেন যেমন: (x+y) ==(x&y)+(x|y) ==(x^y)+2*(x&y)। গড় গণনা করার জন্য, আপনার যা দরকার তা হল দুই দ্বারা সামান্য বিভাজন, যা আপনি একটি ডান শিফট অপারেটরের মাধ্যমে পেতে পারেন।
আপনি দুটি ধনাত্মক পূর্ণসংখ্যা গড় করতে পারেন যেমন:(x&y)+((x^y)>>1)
দ্রুত ইনভার্স স্কয়ার রুট
আমি সবচেয়ে কিংবদন্তি উদাহরণগুলির একটি অন্তর্ভুক্ত না করে বিট টুইডলিং-এ একটি ব্লগ পোস্ট করতে পারিনি। এটি জন কারম্যাকের দ্রুত বিপরীত বর্গমূল অনুমান, 1999 কোয়েক 3 এরিনা সোর্স কোড থেকে। অ্যালগরিদমটি তার নয়, তবে সবচেয়ে বিখ্যাত বাস্তবায়ন হল৷
৷আমি রুবিতে এটির একটি সরাসরি পোর্ট করার চেষ্টা করতে যাচ্ছি না, যেহেতু এটি একটি ভাসমান বিন্দু সংখ্যার একটি বাইনারি উপস্থাপনা তৈরি করে এমনভাবে কাজ করে যা সরাসরি 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;
}