زبان C شش تا عملگر برای کار با بیتها داره. این عملگرها فقط روی نوعهای عددی صحیح (مثل char, short, int, و long — چه signed چه unsigned) قابل استفاده هستن:
& عملگر AND بیتی
| عملگر OR بیتی (شاملکننده)
^ عملگر XOR بیتی (اختصاصی)
<< شیفت به چپ
>> شیفت به راست
~ مکمل یک (عملگر یکتایی)
🔹 عملگر & (AND بیتی) معمولاً برای ماسکگذاری یا خاموش کردن بعضی بیتها استفاده میشه. مثلاً:
n = n & 0177;
باعث میشه همهی بیتهای بالاتر از ۷ بیت پایینی صفر بشن.
🔹 عملگر | (OR بیتی) برای روشن کردن بیتها به کار میره. مثلاً:
x = x | SET_ON;
هر بیتی از x که در SET_ON برابر ۱ باشه، روشن (۱) میشه.
🔹 عملگر ^ (XOR بیتی) هر بیتی رو ۱ میکنه فقط اگه بیتهای دو عملوند متفاوت باشن، و اگه برابر باشن اون بیت صفر میشه.
باید حواست باشه که & و | (بیتی) با && و || (منطقی) فرق دارن.
اون دوتای منطقی برای بررسی "درست یا غلط بودن" استفاده میشن و از چپ به راست ارزیابی میشن.
مثلاً اگه x = 1 و y = 2 باشن،
x & y مقدارش صفره، ولی x && y مقدارش یکه!
🔹 عملگرهای شیفت << و >> مقادیر رو به چپ یا راست حرکت میدن.
مثلاً x << 2 مقدار x رو دو بیت به چپ میبره و جاهای خالی رو با صفر پر میکنه — یعنی در واقع x رو در ۴ ضرب میکنه.
در شیفت راست، اگه مقدار unsigned باشه، بیتهای خالی با صفر پر میشن.
اما اگه مقدار signed باشه، بعضی ماشینها بیت علامت (sign bit) رو پر میکنن (بهش میگن "شیفت حسابی")،
و بعضی دیگه با صفر پرش میکنن ("شیفت منطقی").
🔹 عملگر ~ (مکمل یک) برعکسکنندهی بیتهاست — یعنی هر ۱ رو به ۰ و هر ۰ رو به ۱ تبدیل میکنه.
مثلاً:
x = x & ~077;
شش بیت آخر x رو صفر میکنه.
این روش از نظر طول کلمه (word length) مستقل و قابل حمله (portable).
چون ~077 یه عبارت ثابت محسوب میشه و در زمان کامپایل محاسبه میگرده،
بنابراین هیچ هزینهی اضافی هم نداره.
حالا برای درک بهتر، تابع getbits(x, p, n) رو در نظر بگیر که قراره n بیت از عدد x رو از موقعیت p (بهصورت راستچین) برگردونه.
فرض میکنیم موقعیت بیت ۰، در سمت راستترین بیت قرار داره و n و p مقادیر منطقی و مثبت هستن.
مثلاً:
getbits(x, 4, 3) بیتهای شمارهی ۴، ۳ و ۲ از x رو (بهصورت راستچین) برمیگردونه.
/* getbits: get n bits from position p */
unsigned getbits(unsigned x, int p, int n)
{
return (x >> (p+1-n)) & ~(~0 << n);
}
توضیحش اینطوره:
عبارت (x >> (p+1-n)) باعث میشه قسمت موردنظر از بیتها بره به سمت راست کلمه.
~0 یعنی همهی بیتها برابر ۱ هستن.
وقتی ~0 << n رو مینویسیم، n تا بیت سمت راست صفر میشن.
و وقتی ~ بزنیم روی اون، یه ماسک درست میشه که n تا بیت سمت راستش ۱ هستن.
تمرین ۶-۲: تابعی بنویس به اسم setbits(x, p, n, y) که n بیت شروعشده از موقعیت p در x رو با n بیت سمت راست y جایگزین کنه، در حالی که بقیهی بیتها تغییر نکنن.
تمرین ۷-۲: تابعی بنویس به اسم invert(x, p, n) که n بیت شروعشده از موقعیت p در x رو برعکس کنه (یعنی ۱ها رو ۰ و برعکس)، بدون اینکه بقیهی بیتها تغییر کنن.
تمرین ۸-۲: تابعی بنویس به اسم rightrot(x, n) که عدد x رو به اندازهی n موقعیت به سمت راست بچرخونه (rotate کنه).