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

كيفية تدوير البتات

بدأه C++er في 10 يونيو 2012 · 17 رد · 1,315 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

توجد أساليب كثير لتدوير البتات داخل رقم 32bit او 64bit و لكن أغلب هذه الطرق تتطلب ضعف مساحة النوع المدخل و لا توجد مشكله إذا كان مساحة النوع 4 بايت او 8 بايت و لكن عندما تكون 1024 بايت فمن الصعب جدا جدا كتابة داله لتدوير مثل هذا الرقم بهذه الطرق و لابد من وجود طرق أخرى.

السؤال هو كيف يمكن كتابة دالة لتدوير رقم صخم - 32 بايت على سبيل المثال - فقط بإستخدام متغير unsigned او بحد اقصي unsigned long long.

و لكن مهلا لا تبدا فى محاولة الحل الأن، رقم بمثل هذه المساحه سيصعب عليك جدا جدا تتبعه لذا إليك هذا المثال و حاول كتابة خوارزميه عليه و إن نجحت فلك 25 نقطه، الرقم هو 0xABCDEF37 و مسموح لك بإستخدام 4 بت فقط أثناء التدوير و التدوير سيكون بعدد 8 و 9 و 16 و 17 و 24 و 25 و النتائج المفترض التى تنتجها الخوارزميه كالتالي:

rol(0xABCDEF37,  8) = 0xcdef37ab
rol(0xABCDEF37,  9) = 0x9bde6f57
rol(0xABCDEF37, 16) = 0xef37abcd
rol(0xABCDEF37, 17) = 0xde6f579b
rol(0xABCDEF37, 24) = 0x37abcdef
rol(0xABCDEF37, 25) = 0x6f579bde

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

و الله ولي التوفيق

2

مدونتي: C++ Tips and Tricks

#2

هذا هو الكلام الرائع ... شكرا لك أستاذنا المشرف ...

وكإضافة بسيطة لمن لا يعرف التدوير ...

التدوير هو عملية ثنائية (أي بالنظام الثنائي)وتتم بإزاحة الرقم لليمين أو لليسار عددا من المرات وكل عدد يخرج من اليمين نعود لإدخاله من اليسار...والعكس بالعكس

إذا أردنا تدوير عدد عشري فعلينا تحويله للثنائي ثم تدويره ثم إعادته ... وتدوير العدد الست عشري كذلك ...

وهذا مثال على التدوير لليمين :

Jqj14548.png

مثال آخر ..

لدينا 0x01256360 ست عشري نريد تدويره بمقدار 5 ... كيف ؟ افتح الحاسبة في الويندوز واضغط alt+3 والآن ستظهر لديك الشاشة التالية :

0QR15326.png

والآن اضغط الأسهم الحمراء ثم اكتب الرقم و واضغط السهم الأخضر خمس مرات ...

وهكذا ...

ويمكننا ملاحظة كيف أن التدوير هو عملية دورية دورها هو عدد المنازل ... فالتدوير بمقدار 8 لرقم ثنائي من 8 منازل هو نفس الرقم

والتدوير بمقدار 10 لرقم من 8 منازل هو نفسه التدوير بمقدار 2

وعلى هذا لن نحتاج للتدوير بمقدار أكبر أو يساوي عدد المنازل ...

أشكرك أستاذنا المشرف ... على هذا الاهتمام فينا ... أرجو أن ينقح ما ذكرت عن التدوير إن كان فيه أي خطأ ... جزاه الله خيرا ... والسلام عليكم

#3

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

جزاك الله خيرا أستاذنا الفاضل ... وإليك هذا الحل ...

أولا الخوارزمية:

uVy94933.png

ثانيا مثال بسيط :

jee94933.png

ثالثاً الكود البرمجي بلغة ++C

#include<iostream.h>
unsigned int rol(unsigned int num,unsigned int&rot)
{
	bool Mosty;
	for(char i=0;i<rot;i++)
	{
		Mosty=num&0x80000000;
		num=num<<1;
		num+=(Mosty==1?0x1:0x0);
	}return num;
}
void main()
{
	unsigned int num=0xabcdef37;
	unsigned int rot[6]={8,9,16,17,24,25};
	//cout<<"Enter Num : \n";
	//cin>>num;
	//cout<<"Enter Times Rotating";
	//cin>>rot;
	//rot%=32;
	for(int i=0;i<6;i++)
	{
		cout<<"rol( 0x"<<hex<<num<<" , "<<dec<<rot<<" ) = \t0x"<<hex<<rol(num,rot)<<endl;
	}
}

وإليك مخرجات البرنامج :

WeA94933.png

وأكرر شكري لك أستاذي الفاضل ... وننتظر المزيد من الأسئلة من هذه النوعية الرائعة ... شكرا لك والسلام عليكم

#4

اخى مصطفى أظنك فهمت السؤال بشكل ليس كامل

السائل اخونا محمد علاء يسئل كيف يمكن دوير متغير بطول 8192 بت بــ 4 بت فقط .

كيف يمكن تدوير هذا الرقم الضخم باستخدام متغير بطول 4 بت فقط.

لكى ابسط عليك الامر تخيل لن لديك المتغير بطول 8 بايت كــ unsigned int كيف يمكن تدويرة بمتغير بطول 4 بت.

ان ماذكرتة من مجهود يحسب لك فى فهم آلية عمل تدوير المتغيرات

لو ان السؤال كما توقعت لما وضعة محمد علاء الدين.

هذا والله ولى التوفيق

تم تعديل هذه المشاركة بواسطة محمد عودة في 23 يونيو 2012 في 20:28

1

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#5
اقتباس
لو ان السؤال كما توقعت لما وضعة محمد علاء الدين

+1

لو كان السؤال بهذه البساطة لما وضع الأستاذ محمد علاء الدين له 25 نقطة !! :wink:

تم تعديل هذه المشاركة بواسطة khaled_prg في 13 يونيو 2012 في 21:20

#6

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

السؤال الذى طرحة أخونا محمد علاء لكى تفهم لابد:

  1. معرفة جيدة بالعمليات على مستوى البت Bit Manipulation Operation وهذا مرجع قيم Bitwise operation
  2. ان تتعرف على افكار حول انشاء انواع بيانات رقمية كبيرة مثل رقم بطول 1024 بت وهكذا من هنا C++ Integer Class .
  3. تبحث فى موضوع Big integer bit rotation وهوموضوع السؤال والبدايةمن هنا Big integer bit rotation

هذا الموضوع قد يأخذ معك وقت الا لغير المختصين بهذة العمليات

هذا والله من وراء القصد

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#8

لا ادري ان كان اعتقادي صحيح ولكني اظن ان مفتاح الحل في الارقام 8و9و16و17و24و25 حيث ان البيتات التي تكون قيمتها واحد هي 2^0و 2^3 و 2^4

هذا فقط اعتقادي الاولي

ولو اني لم افهم كيف تعني استخدام الرقم ذو ال4 بيت كmask او كعدد للتدوير

تحياتي

تم تعديل هذه المشاركة بواسطة mental-driller في 14 يونيو 2012 في 21:17

1

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#9
اقتباس
ولو اني لم افهم كيف تعني استخدام الرقم ذو ال4 بيت كmask او كعدد للتدوير

كل 4 بت تساوى رقم واحد بالنظام السادس عشر

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#10
محمد عودة كتب:

كل 4 بت تساوى رقم واحد بالنظام السادس عشر

معروف ، كل هيكس يساوي 1 nibble

ولكني اريد معرفة ما قصد الاخ محمد بانه المسموح لك فقط استخدام 4 بيت!

شكرا على تجاوبك اخي محمد

تحياتي

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#11

السلام عليكم لقد حللت السؤال من أجل أي حجم للرقم حتى لو كان مليون بايت أي 1ميغا ... وقد قمت بالحل باستخدام بت واحد فقط ...

لا أدري إن كان هذا أبسط من الحل الأول على أي حال ... الفكرة بسيطة جداً والحمد لله ... سأضع الكود الآن وأضع الخوارزمية خلال نصف ساعة ...

هذا الكود يستخدم 2بت فقط ... وكود البت الواحد بعد نصف ساعة ...

//2Bit Rotating By mostafa 36a2
#include<iostream.h>

void rol(int*number,int size,int rotTimes=1);
void DisplayNumber(int*number,int size);

void main()
{
	int number[8]={0x12345678,0x9abcdef0,0x12345678,0x9abcdef0,0x98746546,0xabcd8564,0x99226644,0x20adcf22};
	DisplayNumber(number,8);
	for(int i=0;i<8;i++)
	{
	rol(number,8);
	DisplayNumber(number,8);
	}
	for(;;);
}
void rol(int*number,int size,int rotTimes)
{
	bool Bit1;
	bool Bit2;
	for(int rot=0;rot<rotTimes;rot++)
	{
	Bit1=number[0]&0x80000000;cout<<Bit1<<endl;
	number[0]=number[0]<<1;
	for(int i=1;i<size;i++)
	{
		Bit2=number&0x80000000;
		number=number<<1;
		number[i-1]+=Bit2;
	}
	number[size-1]+=Bit1;
	}
}
void DisplayNumber(int*number,int size)
{
	cout<<"\n\n\nThis Number Stored Like This:\n";
for(int	i=0;i<size;i++)
	{
		cout<<&number<<" --> 0x"<<hex<<number<<endl;
	}
}

أنا مضطر للذهاب بالآن لذلك نتابع بعد نصف ساعة ... (كنت أحجز مكاني فقط )

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 15 يونيو 2012 في 16:28

#12

السلام عليكم ...

تدوير رقم ضخم باستخدام بت واحد فقط ...

لنبدأ أولا بالفكرة الرئيسية وهي تخزين الرقم كمصفوفة :

Q7R65894.png

والآن إليكم الخوارزمية حيث أن الرقم سيخزن عملياً بشكله الثنائي :

LEq68613.png

والآن إليكم كود برمجي بلغة ++C (مجرد تطبيق بسيط ) ...

يمكنك التأكد من صحة التدوير حيث أن التدوير بنفس حجم الرقم سيكون نفس الرقم ... الذي تضعه ..

//Rotating By ONLY ONE BIT 
//By mostafa 36a2 
//theprinceofninja@yahoo.com
#include<iostream.h>

void rol(int*number,int size,int rotTimes=1);
void DisplayNumber(int*number,int size);

void main()
{
	int number[8]={0x12345678,0x9abcdef0,0x12345678,0x9abcdef0,0x98746546,0xabcd8564,0x99226644,0x20adcf22};
//هنا كتبنا الرقم جزءا جزءا كما سيخزن في الذاكرة
	DisplayNumber(number,8);
	for(int i=0;i<64;i++)
//سنقوم بالتدوير حتى نصل إلى دور تدوير الرقم وهو 8*8 ثم ستتكرر الأرقام المدورة  (وسيتم عرضها واحدا واحدا حتى تتأكد من صحة التدوير ) 
	{//cout<<"rol number "<<dec<<i+1<<endl;
	rol(number,8);
	DisplayNumber(number,8);
	}
	for(;;);
}
void rol(int*number,int size,int rotTimes)
{
	bool Bit1;
	for(int rot=0;rot<rotTimes;rot++)
	{
	Bit1=number[0]&0x80000000;
	for(int i=0;i<size-1;i++)
	{
		number=number<<1;
		number+=bool(number[i+1]&0x80000000);
	}
	number[size-1]=number[size-1]<<1;
	number[size-1]+=Bit1;
	}
}
void DisplayNumber(int*number,int size)
{
	cout<<"\n\n\nThis Number Stored Like This:\n";
for(int	i=0;i<size;i++)
	{
		cout<<&number<<" --> 0x"<<hex<<number<<endl;
	}
}
/*
الحمد لله الذي فهمني ويسرلي 
هذا من فضل ربي 
والحمد لله رب العالمين 
اللهم أعنا على ذكرك وشكرك وحسن عبادتك 
ولا إله إلا الله وحده لا شريك له له الملك وله الحمد يحيي ويميت وهو على كل شيء قدير
*/
//mostafa 36a2

happy.gif

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

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 15 يونيو 2012 في 16:58

#13

أخى اعذرنى احيانى عدم فهمى الجيد للاكود يجعلنى اخطأ فى التلميحات...

لقد استخدمت:

اقتباس
number = number << 1;

أنت استخدمت متغير أكبر من 4 بت لعمل التدوير .

عقدة السؤال هو عندما تحتاج الدوير لعدد بت واحد وانت مطلوب منك 4 بت.

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#14

خط التليفون عندى فاصل و للأسف لن استطيع المتابعه إلا قبل يوم الإثنين.

يا جماعه لقد فهمتم السؤال بشكل خاطئ، الفكره بشكل اساسي انا عايز اقوم بتدوير رقم يحجز مساحة 256 عنصر من نوع unsigned int و طبعا لو السؤال تم وضعه بالشكل ده هيبقيصعب جدا جدا وضع افكار للحل و لهذا قمت بعملية حسابيه تبسيط المدخلات من السابق إلى تدوير رقم بمساحة 32 بت بإستخدام 4 بت فقط.

قمت بكتابة تحليل مفصل لهذه المشكله و قمت بتقسيمها إلى 3 أجزاء قمت بحل اول جزئين منها و يتبقي الجزء الثالث، يمكنك قرائته داخل موقع stackoverflow من هنا.

اقتباس
تبحث فى موضوع Big integer bit rotation وهوموضوع السؤال والبدايةمن هنا Big integer bit rotation

أخ محمد عوده، هذا السؤال انا من وضعه و لكن داخل موقع stack overflow و لا اعرف كيف تم نقله لهذا الموقع.

اقتباس
متى تنتهي المسابقة في الغد إن شاء الله سأضع حلي إن وصلت إليه ^_^

السؤال مفتوح حتى يتم الوصول للحل، من الجميل ان أرى مشاركتك أخي خالد.

و الله و لي التوفيق

مدونتي: C++ Tips and Tricks

#15
اقتباس
أخ محمد عوده، هذا السؤال انا من وضعه و لكن داخل موقع stack overflow و لا اعرف كيف تم نقله لهذا الموقع.

انا وجدت سؤالك فى موقع stackoverflow.com تقربيا بعد اضافة بوقت قليل جدا ثم بعدها بيومين بحثت بنفس عنوان الموضوع فوجدت الموضوع بالموقع الثانى.

بسسب ضيق وقتى ، فوضعت الروابط لكى يستفيد الاعضاء فى استكمال حل السؤال.

هذا والله من وراء القصد

تم تعديل هذه المشاركة بواسطة محمد عودة في 15 يونيو 2012 في 21:43

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#16

السلام عليكم

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

أرجو أن تكون الملاحظات أوضح ... جزاك الله خيرا

أستاذ علاء الدين ... اليوم هو الاثنين ..

هل يمكنك تصحيح محاولتي أو على الأقل التعليق عليها ... حتى أفكر في الحل الصحيح ...

وإن كانت محاولتي خاطئة ...فأرجو أن تعيد شرح المشكلة فقد قرأت السؤال عشر مرات قبل أن أجيب ... وجزاك الله خيرا والسلام عليكم ....

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 19 يونيو 2012 في 16:24

#17

كنت مشغول الفتره الماضيه كثيرا، و ها قد عدنا.

@مصطفي:

أولا: التدوير بمقدار 1 بت هو سئ جدا على مستوى مساحة الذاكرة المستهكله و ايضا على مستوى الوقت المستغرق فى اتمام العمليه، فالمعالج فى كل الاحوال سيتعامل مع مساحة بيانات أكبر ما تكون بحجم المسجل الخاص به و بالتالي 1 بت من 32 بت - فى مثل هذه الحاله - هو خساره فادحه. بالنسبه الوقت المستغرق فهو فى كل الأحوال ابطء من إستخدامك لـ 2 بت و بالمثل مع 4 بت و هكذا و صولا للـ 32 بت.

ثانيا: الكود الموجود بالمشاركه الثالثه و المشاركه الثانية عشر يخالف ما طلبته حيث الأمر كان تدوير 32 بت فقط بإستخدام 4 بت.

أرجو قراءة الموضوع الموجود بـ stack overflow لمزيد من التوضيح

اقتباس
لا ادري ان كان اعتقادي صحيح ولكني اظن ان مفتاح الحل في الارقام 8و9و16و17و24و25 حيث ان البيتات التي تكون قيمتها واحد هي 2^0و 2^3 و 2^4

هذا فقط اعتقادي الاولي

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

اقتباس
ولو اني لم افهم كيف تعني استخدام الرقم ذو ال4 بيت كmask او كعدد للتدوير

الامر هو موضوع نسبي فتدوير 8192بت بإستخدام 32بت تتطلب تخطيط سليم و ذلك لأن المساحه المتاحه صغيره، بالمثل تدوير 32بت فقط بإستخدام 4بت تعطي نفس التأثير.

و الله ولي التوفيق

مدونتي: C++ Tips and Tricks

#18

والله حتى الآن لم أفهم أين الخطأ ؟؟

اقتباس

التدوير بمقدار 1 بت هو سئ جدا على مستوى مساحة الذاكرة المستهكله

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

اقتباس

و ايضا على مستوى الوقت المستغرق فى اتمام العمليه، فالمعالج فى كل الاحوال سيتعامل مع مساحة بيانات أكبر ما تكون بحجم المسجل الخاص به و بالتالي 1 بت من 32 بت - فى مثل هذه الحاله - هو خساره فادحه. بالنسبه الوقت المستغرق فهو فى كل الأحوال ابطء من إستخدامك لـ 2 بت و بالمثل مع 4 بت و هكذا و صولا للـ 32 بت.

لم يكن عامل الوقت من ضمن السؤال في الأصل ... وعلى أي حال العملية لا تستغرق أكثر من جزء من الثانية... أؤكد أنك لم تذكر شيء عن الوقت في السؤال...

اقتباس

ثانيا: الكود الموجود بالمشاركه الثالثه و المشاركه الثانية عشر يخالف ما طلبته حيث الأمر كان تدوير 32 بت فقط بإستخدام 4 بت.

لماذا ؟؟ المشاركة الثالثة حلت المسألة بالنسبة ل32 بت ... والثالثة عشر لأي حجم ..

كيف يمكن حجز 4 بت أصلا ... سنحجز بايت واحد سواء أردنا تدوير 32 بت أو 32بايت أو 8196 بايت ...

لا أعرف أين المشكلة ... أرجو منك أستاذي ان تعيد صياغة السؤال بشكل أفضل بدل من أن نزعجك بالحلول الخاطئة ...

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

والله ولي التوفيق ...

والسلام عليكم

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 22 يونيو 2012 في 16:44

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