Skip to content
العودة إلى المدوّنة
دروس تعليمية

عمليات البت الكاملة: AND وOR وXOR والإزاحات وأقنعة البتات

أتقن عمليات البت: AND وOR وXOR والإزاحات والمتمم الثنائي وأقنعة البتات ورايات الميزات، مع تسعة أنماط حفظية وأمثلة تشغيل بـ JS وPython وGo وC ومصائد اللغات.

17 دقيقة للقراءة

عمليات البت الكاملة: AND وOR وXOR والإزاحات وأقنعة البتات

تفتح ملف هجرة PostgreSQL قديمًا فتصادف permissions & 0b100. يطلق زميل في الفريق نظام رايات ميزات يحزم 32 قيمة منطقية في عدد صحيح واحد. يُخرج حساب شبكة فرعية في Kubernetes القيمة 192.168.1.0/24، وتحتاج إلى استخراج عنوان الشبكة برمجيًا. ثلاثة مواقف تشترك في مهارة واحدة: عمليات البت.

أغلب مطوري طبقة التطبيق لا يحتاجون & أو ^ في تطبيق ويب، حتى يحتاجونها فجأة. يغطي هذا الدليل مشغلات البت الستة، والمتمم الثنائي، وتسعة أنماط تستحق الحفظ، ثم المصائد الخاصة بكل لغة (وخاصة JavaScript). الأمثلة بلغات JS وPython وGo وC، وكلها قابلة للتشغيل.

افتح محوّل الأساس في علامة تبويب جانبية؛ عدة أقسام تدعوك إلى كتابة عدد ومراقبة نمط البتات وهو يتغير.

لماذا لا تزال عمليات البت مهمة في 2026

لم تجعل اللغات عالية المستوى عمليات البت بائدة، بل أخفت مكان حدوثها فقط. هذه أماكن تعتمد عليها اليوم سواء انتبهت إلى ذلك أم لا:

  • أمان مستوى الصف في PostgreSQL يخزن امتيازات ACL (SELECT, INSERT, UPDATE, DELETE…) في خريطة بت داخل عدد صحيح.
  • قدرات Linux تستبدل النموذج القديم “جذر أو لا شيء” بأكثر من 40 بت صلاحية تجمعها بـ|.
  • رؤوس JWT ترمّز نوع التجزئة في حقل صغير، والمقارنة على مستوى البت شائعة في طبقة المكتبات.
  • Snowflake وULID وUUIDv7 تحزم الطابع الزمني ومعرف الآلة ورقم التسلسل في عدد صحيح 64 أو 128 بت عبر إزاحة يسارية.
  • Redis BITCOUNT وBITOP يعرضان أوليات البت مباشرة لكود التطبيق، لتقدير العدد الأساسي وتقسيم A/B.
  • معالجة الصور تقرأ بكسلات RGBA بحجم 32 بت وتستخرج القنوات بـ& و>>.

عمليات البت تبقى عند O(1) على مستوى تعليمة المعالج. حزم 32 قيمة منطقية في عدد صحيح واحد يوفر 31 بايتًا من الذاكرة، ويسمح باختبار “هل أيٌّ من هذه الرايات الـ32 مفعّل؟” بمقارنة واحدة != 0.

أساسيات ثنائية تحتاج إليها أولًا

يفترض هذا الدليل أنك تفهم الثنائي. إن احتجت إلى مراجعة، اقرأ دليل تحويل الأساس العددي ثم ارجع إلى هنا.

مراجعة سريعة للمصطلحات:

  • البت هو 0 أو 1.
  • النيبل أربعة بتات (رقم سداسي عشري واحد).
  • البايت ثمانية بتات.
  • الكلمة عادة 32 أو 64 بتًا حسب المعالج.

الأعداد الصحيحة في أغلب اللغات ثابتة العرض: 8 أو 16 أو 32 أو 64. العرض يهم كثيرًا في عمليات البت، لأن الإزاحات قد تدفع بتات خارج الحافة، ولأن بت الإشارة يقع في أقصى اليسار للأعداد المُوقَّعة.

جرب الآن: افتح محوّل الأساس، أدخل 170 كقيمة عشرية، وانظر إلى الخرج الثنائي. ستجد 10101010، وهو نمط متناوب سنعود إليه عدة مرات.

مشغلات البت الستة

تقدّم كل لغة رئيسية نفس المشغلات الستة، بفروق تركيبية طفيفة. الرموز & و| و^ و~ و<< و>> تعمل بالطريقة ذاتها في JavaScript وPython وGo وRust وC وC++ وJava وC#. تضيف JavaScript مشغلًا إضافيًا: >>>، وهو إزاحة يمنى غير موقّعة.

AND (&): مرشّح البتات

بت النتيجة يكون 1 فقط إذا كان كلا بتي الإدخال 1.

ABA & B
000
010
100
111

تخيّل AND كبوابة لا يمر منها إلا البتات المضاءة في كلا المعاملين. أكثر استخدام شيوعًا هو القناع: الاحتفاظ ببعض البتات وتصفير الباقي.

// استخراج البتات الأربعة السفلى (النيبل الأيمن)
const value = 0b11010110;   // 214
const low4  = value & 0x0F; // 0b00000110 = 6

// فحص الزوجية
const isOdd = (n) => (n & 1) === 1;
isOdd(7);  // true
isOdd(42); // false
# نفس الشيء في Python
value = 0b11010110
low4 = value & 0x0F  # 6

def is_odd(n):
    return (n & 1) == 1

OR (|): مُفعِّل البتات

بت النتيجة يكون 1 إذا كان أحد بتَي الإدخال على الأقل 1.

ABA | B
000
011
101
111

OR يجمع الرايات. إذا كانت READ = 1 وWRITE = 2 وEXECUTE = 4، فإن READ | WRITE تساوي 3، أي أن كلا الصلاحيتين مفعّلتان.

const READ  = 0b001;
const WRITE = 0b010;
const EXEC  = 0b100;

const rw = READ | WRITE;  // 0b011 = 3
READ, WRITE, EXEC = 0b001, 0b010, 0b100
rw = READ | WRITE  # 3

XOR (^): قلّاب البتات

بت النتيجة يكون 1 حين تختلف بتات الإدخال.

ABA ^ B
000
011
101
110

لدى XOR ثلاث خصائص جبرية تقف وراء بعض أذكى الحيل في علوم الحاسوب:

  • a ^ a = 0: أي قيمة مع نفسها تُلغي بعضها.
  • a ^ 0 = a: XOR مع صفر هو الهوية.
  • a ^ b ^ a = b: XOR هو معكوس نفسه.

الخاصية الأخيرة تفسّر ظهور XOR في كل مكان: من فحوصات الزوجية إلى شيفرات التدفق، ووصولًا إلى سؤال المقابلة الشهير “اعثر على الرقم الوحيد غير المكرر في مصفوفة يتكرر فيها كل رقم آخر مرتين”.

// العثور على الرقم الوحيد الذي يظهر مرة فقط بينما يظهر الباقي مرتين
const findUnique = (arr) => arr.reduce((a, b) => a ^ b, 0);
findUnique([4, 1, 2, 1, 2]);  // 4
from functools import reduce
from operator import xor
find_unique = lambda arr: reduce(xor, arr, 0)
find_unique([4, 1, 2, 1, 2])  # 4

NOT (~): عاكس البتات

المشغل الأحادي ~ يقلب كل بت؛ يصبح 0 واحدًا والواحد صفرًا.

~0b00001111  // -16 (JavaScript تجبر 32 بت موقّعة)
~5           // -6
~5  # -6
// Go تستخدم ^ كـ NOT أحادي للبت — انتبه للرمز
var x int8 = 5
fmt.Println(^x)  // -6

كون ~5 = -6 يفاجئ المبتدئين في كل لغة رئيسية تقريبًا. السبب هو المتمم الثنائي الذي نغطيه في القسم التالي. تذكّر فقط: في أي لغة تستخدم المتمم الثنائي للأعداد السالبة (وهي كلها)، تساوي ~x القيمة -(x + 1).

الإزاحة اليسارية (<<): مضاعف قوة اثنين

x << n يزيح كل بتات x إلى اليسار n خانة، ويملأ اليمين بأصفار. رياضيًا، يضرب في 2ⁿ.

1 << 0   // 1    (2^0)
1 << 1   // 2    (2^1)
1 << 3   // 8    (2^3)
1 << 10  // 1024 (2^10 = 1 KiB)

// بناء رايات بتات
const FLAG_ADMIN    = 1 << 0;
const FLAG_EDITOR   = 1 << 1;
const FLAG_REVIEWER = 1 << 2;

جمال 1 << n أنه ينتج عددًا ببت واحد مضاء في الموضع n، وذلك البت يصبح راية.

انتبه إلى الفيضان. في JavaScript، 1 << 31 تساوي -2147483648 (لا 2147483648)، لأن عمليات البت في JS تعمل على أعداد 32 بت موقّعة.

الإزاحة اليمنى (>> مقابل >>>): موقّعة أم مملوءة بأصفار؟

الإزاحة اليمنى تحرّك البتات إلى اليمين. السؤال هو: ما الذي يملأ المواضع اليسرى الشاغرة؟

  • >> (إزاحة يمنى حسابية): تحافظ على بت الإشارة، فتظل الأعداد السالبة سالبة.
  • >>> (إزاحة منطقية/غير موقّعة): تملأ بأصفار. JavaScript هي اللغة الوحيدة التي تملك مشغلًا مخصصًا لذلك.
-8 >> 1   // -4   (بت الإشارة محفوظ)
-8 >>> 1  // 2147483644  (بت الإشارة يُعامَل كبت بيانات)

8 >> 1    // 4
8 >> 2    // 2

في C، يحدد التنفيذ ما إذا كانت >> على الأنواع الموقّعة حسابية أم منطقية. أغلب المترجمات تنفذها حسابيًا، لكن لا تعتمد على ذلك دون تحقق. Go تشترط أن تكون كمية الإزاحة عددًا غير موقّع، وتميز بوضوح بين الأنواع الموقّعة وغير الموقّعة. Python لا تملك >>> لأنها لا تملك أعدادًا ثابتة العرض.

المتمم الثنائي: كيف تخزّن الحواسيب الأعداد السالبة

إذا كانت البتات 0 و1 فقط، كيف تُرمَّز -5؟ الإجابة التي استقر عليها العالم في الستينيات هي المتمم الثنائي، وكل معالج حديث يستخدمه.

المقاربة الساذجة، أي حجز بت للإشارة، بها مشكلتان: ينتهي بك الأمر إلى +0 و-0 معًا (وهذا محرج)، ثم إن دوائر الجمع والطرح ستحتاج إلى فحص بت الإشارة، مما يعقّد العتاد. المتمم الثنائي يحل الأمرين.

القاعدة قصيرة:

  1. اكتب التمثيل الثنائي للقيمة الموجبة.
  2. اقلب كل بت (هذا هو “المتمم الأحادي”).
  3. أضف 1.

مثال محلول لترميز -5 بمتمم ثنائي من 8 بتات:

 5 بالثنائي:            0000 0101
 اقلب كل البتات:          1111 1010   (هذا هو -6 بالمتمم الثنائي!)
 أضف 1:                  1111 1011   ← هذا هو -5

تحقق من ذلك بمحوّل الأساس: أدخل 251 (عشرية) في محوّل الأساس بالأساس 10، فيكون الخرج الثنائي 11111011. في سياق 8 بت موقّعة، 11111011 هي -5، وفي 8 بت غير موقّعة هي نفس النمط لكن قيمته 251. البتات متطابقة، والتفسير مختلف.

هذا يفسّر مفاجأة ~5 = -6. NOT على البت ينتج المتمم الأحادي، والمتمم الثنائي هو المتمم الأحادي زائد 1. لذا:

~x    = -(x + 1)    // يصح في أي لغة بمتمم ثنائي
~5    = -6
~(-3) = 2

للأعداد الصحيحة الموقّعة ذات n بت، يمتد المدى من -2ⁿ⁻¹ إلى 2ⁿ⁻¹ − 1. 8 بت موقّعة تغطي من -128 إلى 127، و32 بت موقّعة تغطي تقريبًا من -2.1 مليار إلى +2.1 مليار.

تسعة أنماط شائعة لمعالجة البتات

تغطي هذه الأنماط التسعة قرابة 95% من معالجة البتات التي ستكتبها. احفظها، وستراها في كل مكان في كود الأنظمة.

إشعال بت: x | (1 << n)

تشغيل البت n مع ترك البقية كما هي.

let flags = 0b0100;
flags = flags | (1 << 0);  // 0b0101

مسح بت: x & ~(1 << n)

إطفاء البت n مع ترك البقية. ~(1 << n) قناع بكل البتات مضاءة ما عدا n.

let flags = 0b0111;
flags = flags & ~(1 << 1);  // 0b0101

تبديل بت: x ^ (1 << n)

قلب البت n بصرف النظر عن حالته الحالية.

let flags = 0b0100;
flags = flags ^ (1 << 2);  // 0b0000
flags = flags ^ (1 << 2);  // 0b0100 مجددًا

فحص بت: (x >> n) & 1

يعيد 1 إذا كان البت n مضاءً، و0 خلاف ذلك. صيغة مكافئة: (x & (1 << n)) !== 0.

const flags = 0b0101;
const isBit2Set = (flags >> 2) & 1;  // 1

عزل البت المضاء الأدنى: x & -x

ينتج قيمة يظل فيها 1 الأيمن من x وحده. تعمل الحيلة لأن -x في المتمم الثنائي هو ~x + 1، فيقلب كل البتات حتى البت المضاء الأدنى وما يشمله.

const x = 0b10110100;
const lowest = x & -x;  // 0b00000100 = 4

هذه هي الحيلة الأساسية داخل أشجار Fenwick (الأشجار المفهرسة ثنائيًا) لحساب مجاميع البادئات بتعقيد O(log n).

عدّ البتات المضاءة (popcount)

حساب عدد البتات 1 في عدد صحيح. أغلب اللغات تملك دالة أصيلة لذلك:

// JavaScript (نسخة يدوية)
const popcount = (n) => {
  let count = 0;
  while (n) { count += n & 1; n >>>= 1; }
  return count;
};
popcount(0b10110100);  // 4
# Python 3.10+
(0b10110100).bit_count()  # 4
// Go
import "math/bits"
bits.OnesCount(0b10110100)  // 4

مبادلة XOR بدون متغير مؤقت

خدعة كلاسيكية لمبادلة عددين صحيحين دون متغير ثالث. لا تستخدمها في الإنتاج (فهي أبطأ من متغير مؤقت وتنكسر إذا أشار a وb إلى نفس الموقع)، لكنها تستحق الفهم.

let a = 5, b = 9;
a = a ^ b;  // a = 5 ^ 9
b = a ^ b;  // b = (5 ^ 9) ^ 9 = 5
a = a ^ b;  // a = (5 ^ 9) ^ 5 = 9
// a = 9, b = 5

اكتشاف قوة 2: (x & (x - 1)) === 0

قوة 2 بها بت مضاء واحد بالضبط. طرح 1 يطفئ ذلك البت ويشغّل كل ما دونه، فتنتج عملية AND صفرًا فقط لقوى 2 (وللصفر أيضًا، لذا نحمي بـx > 0).

const isPow2 = (x) => x > 0 && (x & (x - 1)) === 0;
isPow2(16);  // true
isPow2(17);  // false

فحص فردية سريع: x & 1

أسرع من x % 2 في بعض اللغات، ومكافئ بعد التحسين في أخرى. مفيد في الحلقات الساخنة، أو حين لا تكون قابلية القراءة أولوية.

const isOdd = (x) => (x & 1) === 1;

رايات أقنعة البتات في كود حقيقي

هنا تنتقل عمليات البت من خانة الحيل إلى خانة الممارسة.

32 قيمة منطقية كراية ميزة واحدة

بدلًا من بنية بـ32 حقلًا منطقيًا، احزمها في عدد صحيح:

const FLAGS = {
  DARK_MODE:      1 << 0,
  NEW_NAV:        1 << 1,
  AI_SUGGESTIONS: 1 << 2,
  BETA_EDITOR:    1 << 3,
  // ... حتى 1 << 31
};

let userFlags = 0;
userFlags |= FLAGS.DARK_MODE | FLAGS.AI_SUGGESTIONS;  // تفعيل

if (userFlags & FLAGS.AI_SUGGESTIONS) {
  showSuggestions();
}

userFlags &= ~FLAGS.DARK_MODE;  // إلغاء التفعيل

يخزّن هذا 32 قيمة منطقية في 4 بايت، ويسمح بالاستعلام عن أي مجموعة فرعية بعملية AND واحدة. قواعد البيانات تحب هذا النمط، فعمود واحد يكفي بدل 32.

صلاحيات ملفات Unix

chmod 755 ليس إلا عمليات بت خالصة. الأرقام الثمانية الثلاثة تقابل ثلاث ثلاثيات بت:

7 = 111  (المالك:   rwx)
5 = 101  (المجموعة: r-x)
5 = 101  (الآخرون:  r-x)

جرّبها بنفسك: في محوّل الأساس، اضبط المصدر على ثماني، أدخل 755، وانظر إلى الخرج الثنائي 111101101. هكذا يخزّن نظام الملفات حقل الصلاحيات حرفيًا.

إضافة “كتابة المجموعة” فقط:

const perms = 0o755;
const withGroupWrite = perms | 0o020;  // 0o775

قناع الشبكة الفرعية IP

بمعطى 192.168.1.10/24، استخرج عنوان الشبكة بتطبيق AND مع القناع:

const ip      = 0xC0A8010A;  // 192.168.1.10
const mask    = 0xFFFFFF00;  // 255.255.255.0 (/24)
const network = ip & mask;   // 0xC0A80100 = 192.168.1.0

معرّفات محزومة: Snowflake

Snowflake من Twitter يحزم الطابع الزمني ومعرف الآلة والتسلسل في عدد صحيح 64 بت:

┌─ 1 بت ─┬─── 41 بت ───┬─ 10 بت ─┬─ 12 بت ─┐
│ إشارة  │ طابع زمني    │  آلة    │  تسلسل  │
└────────┴──────────────┴─────────┴─────────┘

ترميز معرّف يحتاج إزاحتين وعمليتي OR:

const id = (BigInt(timestamp) << 22n) |
           (BigInt(machineId) << 12n) |
            BigInt(sequence);

فك الترميز يعكس ذلك بإزاحة يمنى وقناع. للاختيار بين Snowflake وULID وUUIDv7، انظر مقارنة المعرفات الموزعة.

مصائد خاصة بكل لغة

JavaScript: مصيدة الإكراه إلى 32 بت

تحوّل JavaScript المعاملات إلى أعداد 32 بت موقّعة قبل كل عملية بت، ثم تعيدها إلى Number. أي قيمة فوق 2³¹ − 1 = 2147483647 تفيض:

2147483647 | 0   // 2147483647   (لا تزال بخير)
2147483648 | 0   // -2147483648  (فاض!)
4294967295 | 0   // -1           (كل البتات مضاءة، تُفسَّر موقّعة)

للعمل بـ64 بت، استخدم BigInt؛ فلديه مشغلات بت مستقلة بلا حد للعرض:

(2n ** 40n) | 1n  // 1099511627777n

أخطاء أسبقية المشغلات

من أكثر أخطاء البت شيوعًا في الواقع:

// خطأ: يُقرأ كـ (x & (1 == 0)) لأن == أقوى ارتباطًا من &
if (x & 1 == 0) { /* ... */ }

// الصحيح: أقواس
if ((x & 1) == 0) { /* ... */ }

في C وJavaScript وPython وGo وأغلب مشتقاتها، مشغلات المقارنة أقوى ارتباطًا من AND وOR وXOR على البت. عند الشك، ضع الأقواس.

جدول مقارنة اللغات

اللغةإكراه العرض>> للسالبدعم BigInt
JavaScriptتفرض 32 بت موقّعة؛ >>> غير موقّعةحسابيةBigInt بمشغلات منفصلة
Pythonدقة عشوائية، بلا عرض ثابتحسابيةأصيل
Goصارمة؛ كمية الإزاحة يجب أن تكون غير موقّعةحسابية للأنواع الموقّعةmath/big
C / C++تتبع النوع؛ int وunsigned إلخيحدده التنفيذ في الأنواع الموقّعةلا شيء مدمج
Rustصارمة؛ panic عند الفيضان في التصحيححسابية للأنواع الموقّعةu128 / صناديق خارجية

التواء عرض Python اللانهائي

الأعداد الصحيحة في Python بلا عرض ثابت، فيمتد منطق المتمم الثنائي “لانهائيًا” إلى اليسار مفهوميًا. لذلك ~5 تساوي -6 (لا 250 ولا 65530): Python تعامل النتيجة كعدد صحيح سالب، لا كنمط بت ثابت العرض. إن احتجت إلى دلالات التفاف، ضع قناعًا صريحًا:

# محاكاة NOT من 8 بت
(~5) & 0xFF  # 250

فحص حقيقة الأداء في 2026

الحكمة الشائعة تقول إن عمليات البت “دائمًا أسرع”. في 2026، هذا نصف صحيح فقط.

المترجمات تتولى إعادة الكتابة البديهية بنفسها. المُحسِّنات الحديثة تحوّل x * 2 إلى x << 1 تلقائيًا. كتابة x << 1 في كود التطبيق طلبًا للسرعة تحسين شعائري لا يساعد، بل يؤذي قابلية القراءة.

أين يفوز كود البت فعلًا:

  • حلقات رقمية ساخنة: popcount، عدّ الأصفار البادئة أو اللاحقة، محركات شطرنج بلوحات بت.
  • هياكل بيانات مضغوطة: فلاتر Bloom، وroaring bitmaps، وأشجار Fenwick.
  • سجلات العتاد والمدخلات/المخرجات المرتبطة بالذاكرة في المدمج والنواة والبرامج الثابتة.
  • أوليات التشفير: AES وChaCha20 وSHA، وكلها مبنية من XOR والتدويرات والإزاحات.
  • الضغط وفك الضغط: ترميز Huffman، والطول التشغيلي، والأعداد المحزومة.
  • محركات قواعد البيانات: فهارس bitmap، وتنسيقات أعمدة محزومة مثل ترميز قاموس Parquet.

أين لا يساعد: استبدال x % 2 بـx & 1 في دالة منطق أعمال تنفَّذ مرتين لكل طلب. التسريع غير قابل للقياس، وتكلفة قابلية القراءة حقيقية.

الحالة الوحيدة التي تفوز فيها معالجة البتات دائمًا هي بصمة الذاكرة. حزم 32 راية في int يوفّر 31 بايتًا مقارنة بـ32 قيمة منطقية. عند الحجم الكبير، حين نتحدث عن ملايين السجلات أو مليارات الأحداث، يكون هذا الفرق بين تخطيط صديق للذاكرة المؤقتة وعاصفة أخطاء ذاكرة مؤقتة.

مرجع سريع

العمليةالمشغلمثالالنتيجةالاستخدام النموذجي
AND&0b1100 & 0b10100b1000قناع/استخراج
OR|0b1100 | 0b10100b1110دمج الرايات
XOR^0b1100 ^ 0b10100b0110تبديل/كشف فرق
NOT~~0b1100...11110011قناع معكوس
إزاحة يسارية<<1 << 38ضرب في 2ⁿ
إزاحة يمنى>>16 >> 24قسمة على 2ⁿ (موقّعة)
إزاحة يمنى غير موقّعة (JS)>>>-1 >>> 04294967295معاملة كغير موقّعة
إشعال بت n|x | (1 << n)تشغيل
مسح بت n& ~x & ~(1 << n)إطفاء
تبديل بت n^x ^ (1 << n)قلب
فحص بت n&(x >> n) & 10 أو 1اختبار
أدنى بت مضاء& -x & -xعزل
قوة 2&x > 0 && (x & (x-1)) == 0منطقيكشف

الأسئلة الشائعة

ما الفرق بين AND المنطقي (&&) وAND على البت (&

AND المنطقي يعمل على قيم منطقية كاملة ويقطع الحساب قصيرًا، فلا يُقيَّم expr في false && expr أبدًا ويعيد true أو false. أما AND على البت فيعمل على البتات الفردية لأعداد صحيحة ويقيّم الطرفين دائمًا ويعيد عددًا. استخدم && للتحكم في التدفق والشروط، واستخدم & لتصفية البتات وتطبيق الأقنعة على الرايات.

لماذا تساوي ~1 القيمة -2 في أغلب اللغات؟

المشغل ~1 يساوي -2 لأن NOT على البت يقلب كل بت فينتج المتمم الأحادي، وفي تمثيل المتمم الثنائي الذي يستخدمه كل معالج حديث، قلب كل بتات x يكافئ -(x + 1) حسابيًا. لذلك ~1 = -2 و~0 = -1 و~(-1) = 0. القاعدة تنطبق في C وJava وJavaScript وPython وكل لغة تعتمد المتمم الثنائي.

هل x << 1 أسرع فعلًا من x * 2؟

x << 1 ليس أسرع من x * 2 عمليًا في 2026. كل مترجم حديث، سواء GCC أو Clang أو V8 أو Go، يتعرف على الضرب في قوى اثنين ويُصدر نفس تعليمة الإزاحة. استخدم x * 2 حين تقصد الضرب الحسابي لتحسين القراءة، واحتفظ بـ<< حين تتعامل مع البتات عمدًا مثل بناء قناع أو حزم حقل داخل عدد صحيح.

هل JavaScript تدعم عمليات البت بـ64 بت؟

JavaScript لا تدعم عمليات البت بـ64 بت عبر المشغلات القياسية & و| و^ و<< و>>؛ فهي تجبر المعاملات على 32 بت موقّعة أولًا، فيُقتطع أي شيء أعرض. استخدم حرفيات BigInt بدلاً منها (مثل 1n << 40n أو mask & flagsBigInt) للحصول على عمليات بت بدقة عشوائية وبلا فيضان صامت، وهو المطلوب لمعرفات Snowflake أو مزامنة الطوابع الزمنية بدقة نانوثانية.

كيف أعدّ البتات المضاءة بكفاءة؟

لعدّ البتات المضاءة (popcount) بكفاءة، استخدم الدالة المدمجة في لغتك بدل تطبيق يدوي: bits.OnesCount في Go، وInteger.bitCount في Java، و.bit_count() في Python 3.10+، و__builtin_popcount في C/C++. كلها تُعيَّن إلى تعليمة POPCNT واحدة للمعالج على x86 وARM الحديثة، ما يعني دورة واحدة لعد 64 بت.

متى أستخدم رايات قناع البت بدلًا من بنية قيم منطقية؟

استخدم رايات قناع البت حين تحتاج إلى تخزين كثير من الرايات بشكل مضغوط (قواعد بيانات، بروتوكولات شبكة، تنسيقات ملفات ثنائية)، أو لاختبار التوليفات بسرعة عبر flags & REQUIRED_MASK في مقارنة واحدة. استخدم بنية بقيم منطقية حين تكون الحقول من أنواع مختلفة، أو حين تكون قابلية القراءة والتوثيق الذاتي أهم من توفير الذاكرة، أو حين لا يتجاوز العدد الإجمالي حفنة رايات.

ماذا يحدث إذا أزحت بأكثر من عرض البت؟

الإزاحة بكمية أكبر من عرض البت سلوكها يتغير جذريًا بين اللغات. في C/C++ هو سلوك غير معرّف (undefined behavior) ويحق للمترجم فعل أي شيء. في JavaScript، تُؤخذ كمية الإزاحة بمقياس 32، فتصبح قيمة 1 << 32 هي 1 لا 0. في Python لا عرض ثابت، فـ1 << 100 مجرد عدد أكبر. لا تعتمد على سلوك الإزاحة المفرطة، وضع قناعًا على كمية الإزاحة بنفسك إن لزم.

لماذا تعطي ~5 في Python القيمة -6 لا 2؟

الأعداد الصحيحة في Python بلا عرض ثابت، فيمتد المتمم الثنائي مفهوميًا إلى اللانهاية. ~5 تساوي -(5 + 1) = -6، مثل أي لغة ذات متمم ثنائي. إن أردت قيمة “العكس” بـ8 بت وهي 250، ضع قناعًا: (~5) & 0xFF.

هل تشفير XOR آمن؟

تشفير XOR بمفتاح قصير متكرر غير آمن ويُكسر بسهولة عبر تحليل التردد. الحالة الوحيدة الآمنة هي وسادة المرة الواحدة (one-time pad) بمفتاح عشوائي حقيقي بطول الرسالة يُستخدم مرة واحدة فقط؛ هذه لا يمكن كسرها نظرية المعلومات، لكنها غير عملية لأغلب التطبيقات. الشيفرات الحديثة مثل AES وChaCha20 تستخدم XOR داخليًا لكن كخطوة ضمن خطوات كثيرة.

كيف أمثّل عددًا سالبًا بالمتمم الثنائي يدويًا؟

لتمثيل عدد سالب بالمتمم الثنائي يدويًا، اكتب القيمة الموجبة بالثنائي على العرض الهدف، اقلب كل بت (المتمم الأحادي)، ثم أضف 1. مثال: -5 بـ8 بت = 00000101 ← اقلب إلى 11111010 ← أضف 1 ← 11111011. تحقق في محوّل الأساس بتحويل 251 (التفسير غير الموقّع لـ11111011)، وتأكيد أن الخرج الثنائي هو 11111011.

أدوات ذات صلة وقراءات إضافية

مقالات ذات صلة

عرض جميع المقالات