الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

أرجوا شرح هذا الكود

مغلق
بدأه Ahmed H. Alawady في 24 ديسمبر 2005 · 4 رد · 787 مشاهدة · في Microsoft Visual C#.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته

لقد مر علي في أحد الكتب هذا الكود ، ولم أفهمة مع وجود الشرح له

فأرجوا من الإخوة تبسيطة لكي يتم فهمه

class BitArray
{
public BitArray(int length)
{
if (length < 0)
throw new ArgumentOutOfRangeException(...);
this.bits = new int[((length - 1) >> 5) + 1];
this.length = length;
}
public int Length
{
get { return length; }
}
public bool this[int index]
{
get {
BoundsCheck(index);
return (bits[index >> 5] & (1 << index)) != 0;
}
set {
BoundsCheck(index);
if (value) {
bits[index >> 5] |= (1 << index);
} else {
bits[index >> 5] &= ~(1 << index);
}
}
}
private void BoundsCheck(int index)
{
if (index < 0 || index >= length) {
throw new ArgumentOutOfRangeException(...);
}
}
private int[ ] bits;
private int length;
}

والجزء الذي أريد فهمة هو هذه السطور من الكود فقط

this.bits = new int[((length - 1) >> 5) + 1];
return (bits[index >> 5] & (1 << index)) != 0;
bits[index >> 5] |= (1 << index);
bits[index >> 5] &= ~(1 << index);

وهذا هو الشرح الخاص به

1. Store 32 bools in one int.
BitArray uses substantially less memory than a corresponding bool array
by storing the state for 32 bools in one int. (Remember that int is an alias
for Int32.)
2. Implement an indexer:
public bool this[int index]
The BitArray class contains an indexer to allow a BitArray object to be
used in an array-like manner. In fact, a BitArray can be used exactly like a
bool [ ].
BitArray flags = new BitArray(32);
flags[12] = false;
3. Extract the individual bits.
To extract the individual bits, you must shift the bits. For example, the
following expression appears frequently because shifting right by 5 bits is
equivalent to dividing by 32, because 2*2*2*2*2 == 2^5 == 32. Therefore,
the following shift expression locates the int that holds the bit at position
index:
index >> 5
4. Determine the value of the correct bit.
After the correct int is found, the individual bit (out of all 32) still needs to
be determined. You can do this by using the following expression:
1 << index
To understand how this works, you need to know that when you shift an int
left only the lowest 5 bits of the second argument are used. (Again, only 5
bits are used because the int being shifted has 32 bits.) In other words, the
above shift-left expression is semantically the same as the following:
1 << (index % 32)

تم تعديل هذه المشاركة بواسطة Ahmed H. Alawady في 24 ديسمبر 2005 في 23:36

Name : Ahmed H. Alawady

Web Site : Alawady.info

Email : alawady_ahmed@hotmail.com

Tel : +2 012 345 6808

#2

بسم الله الرحمن الرحيم

جواب ما تريد أن تستفسر عنه هو:

كون الكلاس المدرج في المثال يريد عمل مصفوفة من المتحول من النوع بوليان مع الإستفادة من حجم الذاكرة لذلك هو يقوم بتجزئة البايت الواحد إلى بتات أي كل بايت يحوي على 8 بيت أي المتحول من النوع Int حجمه 4 * 8 = 32 أن سوف تقول أنك تعرف هذا ولكن هذه المقدمه

لذلكك في بداية إنشاء الكلاس يعطيك خيار لتمرير حجم المصفوفه مقدر بالبتاتت أي أنك تريد تخزين حجم معين من المتحولات بوليان فلنقل إننا نريد تخزين 32 بايت من نوع بوليان فيجب أن نحجز 4 بايتات أي متحول واحد من النوع Int

فعملية الإزاحة الت يقوم بها هنا تماثل التقسيم على 32 ما معنا هذا الكلام : المتحول الذي يحوي على الرقم 32 يقابل بيتات على النحو التالية : 00000000000000000000000000010000 فنحن نستطيع أن نقوم بإزاحة إلى اليمين أو إلى اليسار أي ما يعادل الضر أو التقسيم في العد الثنائي إذا قمنا بإزاحة إلى اليسار بمقدار واحد يعادل عملية القوة إلى 2 والعكس عملية التقسيم

    int I = 32;
    int J = I >> 1 // result = 16
    int Y = I << 1 // result = 64

عملية الإزاحة مفيدة إذا أردنا الضرب أو التقسم بالمضاعف الرقم 2 لذلك هو يستخدمها في هذا الكلا س كثير

نفترض حجم المصفوفة 33 رقم إستثانئي بحاجة إلى عنصرين في المصفوفة من نوع INT لمعرفة حجم المصفوفة برمجياً يجب أن نقوم بتقسيم العدد الكلي على عدد خانات المتحول INt أي الرقم الكلي / حجم المتحول أو ما يعادله:

  int OrginalLength = length / 32
  // أو مع عملية الإزاحة
  int OrginalLength = length >> 5 // يعادرل التقيم على 32 لأننا نعرف مسبقاً أنه من مضاعفات العدد 2 أو العد الثنائي

وهو يقوم بعملية إنقاص للمتحول بيت واحد لكوننا لا نستطيع إضهار الفواصل في المتحول من النوع INT لمعرفة العدد الكلي فتصبح كما كتب في الأعلى :

تستطيع صياغة الكود بأكثر من طريقة ولكن هو قا بعتماد الإزاحة لإنها الأسرع.

     int OrginalLength = (  ( length - 1 )  >> 5 ) + 1

زهذا ما يفعله أيضاً في معرفة مكان البايت بعكس عملية الإواحة ومن ثم يخبره مع البت المقابل

      bits[index >> 5] |= (1 << index);

أتمنى لك التوفيق

إذا الغموض مازال مستمر نعاود إن شاء الله شرحة بطريقة إخرى عسى أن تكون المشكلة في شرحي

لا تفعل إلا ما تستطيع أن تقوله ولا تقول إلا ما تسطيع أن تفعله

اللهم علمنا ما ينفعنا ونفعنا بما علمتنا وهب لنا من لدنك ولياً مرشدا

كلما أدبني الدهر أراني نقص عقلي ... وإذا ما زدت علماً زادني علماً بجهلي

أخوكم في الله أبو المجد

هيا نتعلم بعض المبادء لنطرق باب الإحتراف ************** جديد الدروس ( Application Domains and Assemblies)

التوقيت في دمشق:

<embed src="http://www.clocklink.com/clocks/0006-Gray.swf?TimeZone=R1T" width="200" height="240" wmode="transparent" type="application/x-shockwave-flash">

#3

السلام عليكم ورحمة الله وبركاته

جزاك الله خيرا

ولكن

اقتباس
إذا الغموض مازال مستمر

أرجوا إعطاء النواتج لكل عملية تقوم بها بعد الترحيل

Name : Ahmed H. Alawady

Web Site : Alawady.info

Email : alawady_ahmed@hotmail.com

Tel : +2 012 345 6808

#4

بسم الله الرحمن الرحيم

كما نعلم مسبقاً أن البايت مؤلف من 8 أجزاء تدعى البيت وهي أصغر وحده ثنائية يتطيع المعالج أن يتعرف عليها وتحوي في طياتها أحد القيم الثنائية أي إما 1 أو صفر. وكل أربع بيتات نستطيع أن نلق عليها أسم نيبل Nibble .

26_12_05_06_30_36_1135607436Byte.jpg

وجميع العمليات الرياضيه التي نجريه تتم على مستوى البيت. لمعرفة محتوى البايت الواحد نجري العملية الرياضية البيسيطه وهي رقم البيت * نظام العد المستخدم * حالة البيت = محتوى البايت الواحد

26_12_05_06_16_07_1135606567BinaryBayte.jpg

من أحد العمليات التي نستطيع أن نجريها البيت هي الإزاحه :

1 - إزاحة إلى اليسار Shift Left Operation:

وهي عملية بسيطة جداً تقوم بإزاحة البيتات إلى اليسار بمقدار وأحد أو حسب الأمر المعطى:

26_12_05_06_36_01_1135607761Shift_Left.jpg

  
                byte I1 = 1 << 1;       // Result = 2
            byte I2 = 1 << 2;       // Result = 4
            byte I3 = 1 << 3;       // Result = 8
            byte I4 = 1 << 4;       // Result = 16
            byte I5 = 1 << 5;       // Result = 32
            byte I6 = 1 << 6;       // Result = 64
            byte I7 = 1 << 7;       // Result = 128
            byte I8 = (1 << 8) - 1; // Result = 256 - 1 = 255

            MessageBox.Show(String.Format("I1 = 1 << 1 = {0}\nI2 = 1 << 2 = {1}\nI3 = 1 << 3 = {2}\nI4 = 1 << 4 = {3}\nI5 = 1 << 5 = {4}\nI6 = 1 << 6 = {5}\nI7 = 1 << 7 = {6}\nI8 = 1 << 8 = {7}\n", I1, I2, I3, I4, I5, I6, I7, I8));

نلاحظ من جميع النتائج التي حصلنا عليها أن الإزاحة إلى اليسار تقابل مجموع الإزاحة مرفوعة إلى القوة 2 وهذه العملية مفيدة عندما يكون لدينا معرفة مسبقه بأن العدد سوف يضرب بقوته فعملية الإزاحة هي أسرع من عملية الضرب

الإزاحة إلى اليمين Shift Right Operation:

وهي عملية بسيطة جداً تقوم بإزاحة البيتات إلى اليمين بمقدار وأحد أو حسب الأمر المعطى:

26_12_05_06_57_48_1135609068Shift_Rightt.jpg

            byte I1 = 256 >> 1; // Result = 128
            byte I2 = 256 >> 2; // Result = 64
            byte I3 = 256 >> 3; // Result = 32
            byte I4 = 256 >> 4; // Result = 16
            byte I5 = 256 >> 5; // Result = 8
            byte I6 = 256 >> 6; // Result = 4
            byte I7 = 256 >> 7; // Result = 2
            byte I8 = 256 >> 8; // Result = 1

            MessageBox.Show(String.Format("I1 = 256 << 1 = {0}\nI2 = 256 << 2 = {1}\nI3 = 256 << 3 = {2}\nI4 = 256 << 4 = {3}\nI5 = 256 << 5 = {4}\nI6 = 256 << 6 = {5}\nI7 = 256 << 7 = {6}\nI8 = 256 << 8 = {7}\n", I1, I2, I3, I4, I5, I6, I7, I8));

نلاحظ من جميع النتائج التي حصلنا عليها أن الإزاحة إلى اليمين تقابل تقسيم العدد على الإزاحة مرفوعة إلى القوة 2 وهذه العملية مفيدة عندما يكون لدينا معرفة مسبقه بأن العدد سوف يقسم بقوته فعملية الإزاحة هي أسرع من عملية التقسيم.

لذلك ترى كما ذكرنا مسبقاً بأنه يستخدم عملية الأزاحة إلى اليمين بمقدار 5 بدلأ من التقسيم على 32 وهذا ما كنا قد أستنتجناه من عملية الإزاحة.

تحليل الكلاس المرفق:

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

بما أن المتحول البولياني لا يحوي إلا قيمتني هي True Or False نستطيع تخزين كل متحول في بيت وواحد لأن طبيعة البيت لا تحوي إلا حالتين وهو قام بستخدام المتحول الـ Int بدلا من البايت لذلك هو يقوم بتقسيم على 32 لماذا؟

كما ذكرنا مسبقاً أن كل بايت يحتوي على 8 بتات فأن المتحول الـ Int الذي يحوي أربع بايتات يحويع على 32 بيت كيف هي ناتج ضرب 4 بايت * 8 بيت لكل بايت الناتج 32.

لذلك عندما تريد أن تختبر المتحول البولياني الذي يحمل الرقم 5 فيجب أي انت تريد معرفة حالة البيت الخامس من المتحول الـ Int يجب في بادئ الأمر أن نقوم بتهيئة متحول يحوي على أحد حالات البوليان هنا يجب أن تكون الحالة True لوضع واحد في ذلك البيت وهذا يأتي عن طريق الإزاحة بمقدار 5 أو العدد الذي نريده:

            int BitResult = (1 << 5);
            int Sample = 255;
            bool Result = (BitResult & Sample) != 0; // True 

            MessageBox.Show(Result.ToString());

لماذا الناتج True بسبب العملية AND تقارن بين البيتات ويكون الناتج كمايلي:

26_12_05_07_25_38_1135610738AND_Truth_Table.jpg

            0 AND 0 = 0
            0 AND 1 = 0
            1 AND 0 = 0
            1 AND 1 = 1

أخي الكريم هذا شرح لأهم ماجاء في الكود الذي تريد شرحه أتمنى أنتقوم بالقراءة أكثر من مره وإذا الغموض مازال مستمر نعاود إن شاء الله شرحة بطريقة إخرى عسى أن تكون المشكلة في شرحي

أتمنى أن يكون الشرح قد أدى الغالية المطلوبه منه.

أتمنى لكم التوفيق

تم تعديل هذه المشاركة بواسطة TarekNajem04 في 26 ديسمبر 2005 في 18:23

لا تفعل إلا ما تستطيع أن تقوله ولا تقول إلا ما تسطيع أن تفعله

اللهم علمنا ما ينفعنا ونفعنا بما علمتنا وهب لنا من لدنك ولياً مرشدا

كلما أدبني الدهر أراني نقص عقلي ... وإذا ما زدت علماً زادني علماً بجهلي

أخوكم في الله أبو المجد

هيا نتعلم بعض المبادء لنطرق باب الإحتراف ************** جديد الدروس ( Application Domains and Assemblies)

التوقيت في دمشق:

<embed src="http://www.clocklink.com/clocks/0006-Gray.swf?TimeZone=R1T" width="200" height="240" wmode="transparent" type="application/x-shockwave-flash">

#5
اقتباس
لذلك عندما تريد أن تختبر المتحول البولياني الذي يحمل الرقم 5 فيجب أي انت تريد معرفة حالة البيت الخامس من المتحول الـ Int يجب في بادئ الأمر أن نقوم بتهيئة متحول يحوي على أحد حالات البوليان هنا يجب أن تكون الحالة True لوضع واحد في ذلك البيت وهذا يأتي عن طريق الإزاحة بمقدار 5 أو العدد الذي نريده

هذا ما كنت أرده

اقتباس
الشرح قد أدى الغالية المطلوبه منه

جزاك الله خيرا

Name : Ahmed H. Alawady

Web Site : Alawady.info

Email : alawady_ahmed@hotmail.com

Tel : +2 012 345 6808

هذا الموضوع مغلق.

مواضيع مشابهة