أساسيات البرمجة بلغة السي شارب · الفصل 10 — عمليات بوليانية على الخانات وموازينפעולות בוליאניות על סיביות ובסיסי ספירה · יסודות התכנות בשפת C#‎⌂📚🏠
الفصل 10

عمليات بوليانية على الخانات وموازين

פעולות בוליאניות על סיביות ובסיסי ספירה

10.1 مقدمة – מבוא

كما تعلمنا يوجد نوع بيانات اسمه byte وهو أصغر من int حيث أنه يستطيع أن يحتوي رقماً صحيحاً بالمجال من 0 حتى 255 يشمل الصفر ويشمل العدد 255.

سنتعامل أحياناً في هذا الفصل مع byte وذلك لسهولة التعامل مع عدد قليل من الخانات حيث أن المتغير من نوع byte يتم تخزينه في الذاكرة في 8 خانات (8 bit) حيث يُعتبر ال byte وحدة ذاكرة صغيرة، بينما مُعطيات من نوع int فانه يتم تخزينها في الذاكرة في 32 خانة.

مثال 10.1
استعمال byte و int
static void Main(string[] args)
{
  int x = 98;
  byte y = 98;
  Console.WriteLine("x={0}", x);
  Console.WriteLine("y={0}", y);
  x++;
  y++;
  Console.WriteLine("*************");
  Console.WriteLine("x={0}",x);
  Console.WriteLine("y={0}",y);
}
Microsoft Visual Studio Debug Console
x=98
y=98
*************
x=99
y=99
intx=98;00000000110001031302928...9876543210x=99;00000000110001131302928...9876543210bytey=98;0110001076543210y=99;0110001176543210

كل خانة تستطيع أن تحتوي على 1 أو 0 بالذاكرة لان الأرقام تُخزن بالميزان الثنائي.

مثال 10.2
int n = 270; ➔ 100001110

هذا الرقم يُخزن في int وهذه الخانات تكون LSB من بين ال 32 خانة (تُخزن من خانة 0 حتى خانة 8) والباقي يكون صفر (أصفار) أي من خانة 9 حتى خانة 31 يكون أصفار.

أي يكون الرقم يُحفظ بالذاكرة على الشكل التالي:

00000000000000000000000100001110

ومنا هنا أفضل لنا التعامل مع نوع بيانات byte إذا اردنا التعامل مع خانات الأرقام. ولكن حتى لو تعاملنا مع المُتغيرات int فاننا سنتعامل مع الخانات الأولى LSB وباقي الخانات التي ستخرج خارج مجال المكمل لل 2 (משלים ל-2) ستكون قيمتها غير صحيحة وذلك لأننا في int نتعامل مع أرقام لها إشارات.

طبعاً هذا الرقم (270) لا يمكن تخزينه بنوع بيانات byte لأنه أكبر من 255 وكما رأينا يحتاج الى 9 خانات لتخزينه (من خانة 0 حتى خانة 8).

مثال 10.3
byte num = 305;لا يُمكن لأن byte لا يستطيع أن يحتويأرقاماً اكبر من 255
مثال 10.4
byte num = 200; ➔ 11001000
11001000

10.2 تعويض أرقام في موازين مختلفة للمتغيرات من داخل البرنامج – הצבת מספרים בבסיסים שונים

في لغة السي شارب نستطيع تعويض أرقاما للمتغيرات داخل البرنامج بواسطة العملية =

(1) تعويض رقم عشري (Dec):

اذا اردنا تعويض رقماً عشريا في المتغير نكتبه مباشرة. مثل:

num = 44; // num = (44)10 = (2C)HEX = (00101100)2

(2) تعويض في الميزان 16 (HEX):

اذا اردنا تعويض رقماً في الميزان 16 (HEX) في المتغير نكتبه بحيث نكتب قبله 0x أو 0X (صفر وحرف x صغير أو كبير). مثل:

num =0x44; // num = (68)10 = (44)HEX = (01000100)2

(3) تعويض في الميزان الثنائي (Bin):

اذا اردنا تعويض رقماً في الميزان الثنائي (Bin) في المتغير نكتبه بحيث نكتب قبله 0b أو 0B (صفر وحرف b صغير أو كبير). مثل:

num =0b10100111; // num = (167)10 = (A7)HEX = (10100111)2

المتغير num يمكنه أن يكون من نوع int أو byte.

10.3 طباعة قيمة متغيرات بموازين مختلفة على الشاشة – הדפסת ערכים בבסיסים שונים

يمكننا تخزين قيم مختلفة داخل المتغيرات وذلك حسب نوعها.

اذا أردنا طباعة قيمة متغير على الشاشة بميزان عشري (الوضع الطبيعي) نستعمل الأمر Console.Write ونستعمل الأداة {} كما يلي:

{0} او {0:d} أو {0:D} داخل الجملة النصية في الامر Console.Write

اذا أردنا طباعة قيمة متغير على الشاشة بميزان 16 (HEX) نستعمل الأمر Console.Write ونستعمل الأداة {} كما يلي:

{0:x} أو {0:X} داخل الجملة النصية في الامر Console.Write

10.4 العمليات على البيانات والمُعطيات – הפעולות על הנתונים

تعلمنا سابقا كل العمليات التالية:

العمليةشرح
+جمع
-طرح
*ضرب
/قسمة
%الباقي من القسمة
++إضافة 1
--تنقيص 1
+=جمع الرقم مع القيمة السابقة
-=طرح الرقم من القيمة السابقة
*=ضرب الرقم مع القيمة السابقة
/=قسمة القيمة السابقة على الرقم
%=باقي قسمة القيمة السابقة على الرقم
فئة Mathحسابات رياضية خاصة
||علاقة أو منطقي في الشروط
&&علاقة وأيضا منطقي في الشروط
==مقارنة (مساواة)
!=مقارنة ( لا يساوي)
<مقارنة (تفاضل)
>مقارنة (تفاضل)
<=مقارنة (تفاضل أو مساواة)
>=مقارنة (تفاضل أو مساواه)

كل هذه العمليات عملت على البيانات المُختلفة بالميزان العشري.

سنتعلم عمليات جديدة على خانات الرقم المُخزنة (خاناته التي تحتوي رقما بالميزان الثنائي 0 أو 1) :

العمليةعملهاشرح
&bitwise Andعملية وأيضا And على كل خانة وخانة من خانات الرقم المُخزنة بالميزان الثنائي
|bitwise Orعملية أو Or على كل خانة وخانة من خانات الرقم المُخزنة بالميزان الثنائي
~bitwise Notعملية نفي Not على كل خانة وخانة من خانات الرقم المُخزنة بالميزان الثنائي
^bitwise XORعملية XOR على كل خانة وخانة من خانات الرقم المُخزنة بالميزان الثنائي
<<Shift Leftإزاحة خانات الرقم المُخزنة بخانة واحدة لليسار
>>Shift Rightإزاحة خانات الرقم المُخزنة بخانة واحدة لليمين
aba | b
000
011
101
111
aba&b
000
010
100
111
a~a
01
10
aba^b
000
011
101
110

ملاحظات:

تحريك خانة لليسار:

aa7a6a5a4a3a2a1a0a<<1a6a5a4a3a2a1a00a7

تحريك خانة لليمين:

bb7b6b5b4b3b2b1b0b>>10b7b6b5b4b3b2b1b0
0001 ←➔ 0010 ←➔ 0100 ←➔ 1000
مثال 10.5
static void Main(string[] args)
{
 int a = 7; // 7 = 00000111
 int b = 2; // 2 = 00000010
 int not_a , not_b,c,d,e;
 not_a = ~a; //not_a=11111000 =>it`s negative so with 2`C it`s negative of 8
 not_b = ~b; //not_b=11111101 =>it`s negative so with 2`C it`s negative of 3
 c = a | b;
 d = a & b;
 e = a ^ b;

 Console.WriteLine("Value of not_a is {0}", not_a);
 Console.WriteLine("Value of not_b is {0}", not_b);
 Console.WriteLine("Value of a|b is {0}", c);
 Console.WriteLine("Value of a&b is {0}", d);
 Console.WriteLine("Value of a^b is {0}", e);
 Console.ReadKey();
}

نتيجة تشغيل البرنامج:

C:\Users\Hammam\source\repos\Co
Value of not_a is -8
Value of not_b is -3
Value of a|b is 7
Value of a&b is 2
Value of a^b is 5

الشرح:

a00000111~a11111000b00000010~b11111101

بعد اجراء عملية Not خانة خانة هنا نرى ان الأرقام التي نحصل عليها سالبة (لان خانة الإشارة 1 (فعالة)) لذلك لكي نعرف ما هي هذه الأرقام السالبة نعمل لها مكمل لل 2 (2`C) وتظهر لنا القيمة الموجبة المضادة لهذه الأرقام السالبة وهكذا نعرف ما هي.

a00000111b00000010a|b00000111= 7a&b00000010=2a^b00000101=5

أمثلة على عمليات إزاحة خانات لليسار (<<) وازاحة لليمين (>>):

static void Main(string[] args)
{
    int a = 11; // 11 = 00001011
    int b = 60;  // 60 = 00111100
    int c,d;
    c = a << 2; // 2 steps left
    d = b >> 2; // 2 steps right

    Console.WriteLine("c is {0}", c);
    Console.WriteLine("d is {0}", d);
}

نتيجة تشغيل البرنامج هي:

C:\Users\Hammam\
c is 44
d is 15
a00001011=11a<<200101100=44خروج منالمجال00دخول أصفار
b00111100= 60b>>200001111= 15خروج منالمجال00دخول أصفار

10.5 استعمال قناع (מיסוך – mask) – שימוש במסכה

الهدف من هذه العملية (تقنية) هو قراءة قيمة خانة مُعينة من كلمة. مثلا نريد أن نفحص ما هي قيمة الخانة السادسة بالرقم 241 (الذي هو 11110001) .

عملية التقنيع (وضع قناع) هي عملية فيها نستعمل عملية And مع قناع الذي يكون فيه خانات صفر في الأماكن التي لا نهتم بها (بالخانات التي لا تهمنا) بينما يكون قيمة الخانة التي تهمنا في القناع هي 1 .

في المثال القناع هو (00100000) جميع الخانات 0 (من الأولى حتى الخامسة والسابعة والثامنة) بينما الخانة السادسة التي نهتم بها بالرقم الأصلي (241) فإننا نضع بالقناع 1 .

هذا يضمن لنا ان كل خانات الرقم الأصلي ستلغى (تصبح صفر لان عمل وأيضا مع صفر سيسبب صفراً بالضرورة) وأما الخانة المرغوب بها فستبقى (لان عملية وأيضا مع الخانة المرغوبة هو بقاء قيمة الخانة المرغوبة على ما هي عليه حيث إن كانت صفراً ستبقى صفراً وإن كانت 1 ستبقى 1)

ثم بعد عملية وأيضاً مع القناع تبقى لنا خانة واحدة في المُعطى ولكن :

خانة8خانة7خانة6خانة5خانة4خانة3خانة2خانة1aa7a6a5a4a3a2a1a0&&&&&&&&قناع00100000a&قناع00a500000"0""1"00000000=000100000=1
مثال 10.6
static void Main(string[] args)
{
  int num = 117;  // 117 = 01110101
  int mask = 0b00010000;  // mask = 16;
  int res;

  res = num & mask;
  if(res==0)
      Console.WriteLine("Bit number 5 in number {0} is 0",num);
  else
      Console.WriteLine("Bit number 5 in number {0} is 1", num);
}

نتيجة تشغيل البرنامج:

C:\Users\Hammam\source\repos\ConsoleApp38\
Bit number 5 in number 117 is 1

معرفة الرقم الذي نستقبله إذا كان زوجي أم لا بدون استعمال مودولو:

معلوم أن الرقم يكون زوجيا اذا كانت اقل خانة فيه LSB بالميزان الثنائي هي 0 بينما اذا كانت أقل خانة فيه LSB هي 1 فان الرقم فردي. لذلك تهمنا هذه الخانة.

اذا أجرينا قناع فيه 1 فقط في الخانة اليمنى LSB أي 00000001 فاننا سنحصل اما على صفر أو 1 بعد عملية التقنيع (And) حيث أنه من سيقرر ذلك هي الخانة الأولى بالرقم الأصلي التي نهتم بها (LSB) .

اذا كانت النتيجة:

سؤال 10.1: اكتب برنامج يستقبل من المُستخدم عددا صحيحاً ويطبع على الشاشة إذا كان هذا العدد زوجي (even) أم فردي (odd) دون استعمال عملية %

الحل:

static void Main(string[] args)
{
   int num;
   int mask = 0b00000001;  // mask = 1;
   int res;

   Console.Write("Insert a number: ");
   num = int.Parse(Console.ReadLine());
   res = num & mask;
   if(res==0)
       Console.WriteLine("The number {0} is even",num);
   else
       Console.WriteLine("The number {0} is odd", num);
}

نتائج تشغيل البرنامج:

C:\Users\Hammam\source
Insert a number: 64
The number 64 is even
C:\Users\Hammam\source\repos\Consol
Insert a number: 37
The number 37 is odd
همام عبد اللطيف وتد — جميع حقوق هذا الكتاب محفوظة للمؤلف. النسخة الإلكترونية منشورة في fahed-lab.com بإذنه، مع تصحيحات وافق عليها. للتواصل مع المؤلف: hammam4112@gmail.com