বাইনারি ডিজিট শেষ পর্যন্ত সরাসরি আপনার CPU বা RAM-এর ট্রানজিস্টরের সাথে মিলে যায়, আর প্রতিটি ট্রানজিস্টর "চালু" না "বন্ধ" আছে সেটার সাথেও।
নিম্নস্তরের ম্যানিপুলেশন, যাকে অনানুষ্ঠানিকভাবে "বিট-টুইডলিং" বলা হয়, সিস্টেম ভাষাগুলোতে বিশেষভাবে গুরুত্বপূর্ণ।
Julia-র মতো হাই-লেভেল ভাষা সাধারণত এই বিশদগুলোর বেশিরভাগই আড়াল করে রাখে। তবে বেস ভাষাতেই বিট-স্তরের অপারেশনগুলোর পূর্ণ সেট পাওয়া যায়।
নোট: REPL-এ মানুষের পড়ার মতো বাইনারি আউটপুট দেখতে নিচের প্রায় সব উদাহরণকেই একটি bitstring() ফাংশনে মুড়ে দিতে হবে। এতে চোখে বিশ্রী লাগে, তাই এই ফাংশনের বেশিরভাগ ব্যবহার এখান থেকে বাদ দেওয়া হয়েছে।
ইন্টিজার টাইপ, সাইনড বা আনসাইনড, ১ আর ০-এর একটি স্ট্রিং হিসেবে প্রকাশ করা যায়।
julia> bitstring(UInt8(5))
"00000101"
বিট-শিফট কেবল সবকিছু নির্দিষ্ট সংখ্যক অবস্থান বামে বা ডানে সরিয়ে দেয়। UInt টাইপে এক প্রান্ত থেকে কিছু বিট পড়ে যায়, আর অন্য প্রান্ত শূন্য দিয়ে ভরাট করা হয়:
julia> ux::UInt8 = 5
5
julia> bitstring(ux)
"00000101"
julia> ux << 2 # left by 2
"00010100"
julia> ux >> 1 # right by 1
"00000010"
প্রতিটি বাম-শিফট মানটিকে দ্বিগুণ করে আর প্রতিটি ডান-শিফট এটিকে অর্ধেক করে (ট্রাঙ্কেশনের সাপেক্ষে)। দশমিক রূপে এটা আরও স্পষ্ট:
julia> 3 << 2
12
julia> 24 >> 3
3
এ ধরনের বিট-শিফট "প্রকৃত" অ্যারিথমেটিকের চেয়ে অনেক দ্রুত, তাই নিম্নস্তরের কোডিংয়ে এই কৌশলটি বেশ জনপ্রিয়।
সাইনড ইন্টিজারের বেলায় আমাদের একটু বেশি সতর্ক থাকতে হয়।
বাম শিফট তুলনামূলক সরল:
julia> sx = Int8(5)
5
julia> sx # positive integer
"00000101"
julia> sx << 2
"00010100"
julia> -sx # negative integer
"11111011"
julia> -sx << 2
"11101100"
তাই ধনাত্মক সাইনড ইন্টিজার বাম-শিফট করা আনসাইনড ইন্টিজারের মতোই।
ঋণাত্মক মান টু'স কমপ্লিমেন্ট আকারে সংরক্ষণ করা হয়, যার মানে বাঁদিকের বিটটি ১। বাম-শিফটে কোনো সমস্যা নেই, কিন্তু ডান-শিফট করার সময় বাঁদিকের বিটগুলো কী দিয়ে ভরাট করব?
julia> sx >> 2 # simple for positive values!
"00000001"
julia> -sx # negative integer
"11111011"
julia> -sx >> 2 # pad with repeated sign bit
"11111110"
julia> -sx >>> 2 # pad with 0
"00111110"
>> অপারেটর অ্যারিথমেটিক শিফট করে, সাইন বিট অক্ষুণ্ণ রেখে।
>>> অপারেটর লজিক্যাল শিফট করে, শূন্য দিয়ে ভরাট করে যেন সংখ্যাটি আনসাইনড।
আগের একটি কনসেপ্টে আমরা দেখেছি যে && (and), || (or) এবং ! (not) অপারেটরগুলো বুলিয়ান মানের সাথে ব্যবহার করা হয়।
দুটি ইন্টিজারের বিট তুলনা করার জন্য সমতুল্য অপারেটর আছে: & (বিটওয়াইজ and), | (বিটওয়াইজ or) এবং ~ (টিল্ডি, বিটওয়াইজ not)।
julia> 0b1011 & 0b0010 # bit is 1 in both numbers
"00000010"
julia> 0b1011 | 0b0010 # bit is 1 in at least one number
"00001011"
julia> ~0b1011 # flip all bits
"11110100"
julia> xor(0b1011, 0b0010) # bit is 1 in exactly one number, not both
"00001001"
এখানে xor() হলো এক্সক্লুসিভ-অর, যা একটি ফাংশন হিসেবে ব্যবহৃত হয়।
আপনার বন্ধু এইমাত্র আপনাকে একটি গুরুত্বপূর্ণ গোপন বার্তা পাঠিয়েছেন। অন্যরা যাতে তা সহজে পড়তে না পারে, তাই একের পর এক বিট ম্যানিপুলেশন করে বার্তাটি এনক্রিপ্ট করা হয়েছে। বার্তাটি ডিক্রিপ্ট করতে সাহায্য করার ফাংশনগুলো আপনাকে লিখতে হবে।
বার্তাটি ডিক্রিপ্ট করার প্রথম ধাপ হলো এনক্রিপশনের সময় করা শিফটটি আগের অবস্থায় ফিরিয়ে আনা, অর্থাৎ বিটগুলোকে আবার ডানে শিফট করা। ডিক্রিপশনের পরের ধাপগুলো ধরে নেয় যে বাম দিক থেকে 0 ঢোকানো হয়েছে।
shift_back() ফাংশনটি লিখুন, যা একটি মান এবং কত ঘর শিফট করতে হবে সেই সংখ্যা নেয় এবং শিফটটি সম্পন্ন করে।
shift_back(0b1001, 2) # => 0b0010
এরপর, কিছু বিট আছে যেগুলোকে 1 সেট করতে হবে।
set_bits() ফাংশনটি লিখুন, যা একটি মান এবং একটি মাস্ক নেয় এবং value-এর বিটগুলোকে 1 সেট করার ফলাফল রিটার্ন করে।
mask-এর যে বিটটি 1, value-এর সেই বিটটি 1 সেট করা উচিত।
বাকি সব বিট অপরিবর্তিত রাখতে হবে।
set_bits(0b0110, 0b0101) # => 0b0111
এনক্রিপশনের সময় কিছু বিট ফ্লিপ করা হয়। বার্তাটি ডিক্রিপ্ট করতে সেগুলো আবার ফ্লিপ করতে হবে।
flip_bits() ফাংশনটি লিখুন, যা একটি মান এবং একটি মাস্ক নেয়।
মাস্কটি বলে দেয় value-এর কোন বিটগুলো ফ্লিপ করতে হবে।
mask-এ কোনো বিট 1 হলে, value-এর সেই বিটটি ফ্লিপ করা হয়।
অন্য সব বিট অপরিবর্তিত রাখা হয়।
flip_bits(0b1100, 0b0101) # => 0b1001
সবশেষে, কিছু বিট আছে যেগুলো সবসময় 0-তে ডিক্রিপ্ট হয়।
clear_bits() ফাংশনটি লিখুন, যা একটি মান এবং একটি মাস্ক নেয়।
mask-এর যে বিটটি 1, value-এর সেই বিটটি 0 সেট করা উচিত।
অন্য সব বিট অপরিবর্তিত রাখা উচিত।
clear_bits(0b0110, 0b0101) # => 0b0010
Exercism-এ সাইন আপ করুন, Julia ট্র্যাকের 35টি কনসেপ্ট128টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।