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

كيف تحسب مضروب عدد باستخدام السي بلس بلس ؟!

مغلق
بدأه باسم الموجي في 24 يناير 2008 · 34 رد · 19,756 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

سؤالي عن حساب مضروب عدد عن طريق السي

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

وأي شخص سيقوم بكتابة البرنامج عليه أن يقوم بحساب مضروب 1000 به ويقارنها بمضروب 1000 من الآلة الحاسبة الموجودة في الويندوز ليتأكد من صحة برنامجه :thumbup:

وتحياتي

تم تعديل هذه المشاركة بواسطة باسم الموجي في 24 يناير 2008 في 16:27

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#2

اليك هذا الكود:

long double factorial (int num) {
	if (num==0) return 1;
	return num * factorial(num-1);
}

لكن عدد المنازل يكون قليل

ولكنه يحسب مضروب 1000

#3

هذا البرنامج لا يستطيع أن يحسب مضروب 171 فأكبر مضروب يستطيع حسابه هو مضروب 170 وجرب بنفسك لتتأكد

1

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#4

السلام عليكم ,,

أخ باسم, أنت تريد طريقة لحساب أعداد طويلة جداً لا تستوعبتها الأنواع الموجودة في ++C/C ,,

حسناً ما رأيك لو قلت لك أن هناك classes جاهزة لفعل هذه الأمور و يمكنك استخدام الجمع و الضرب و القسمة ....... معها كما تستخدمها مع النوع Int B)

إضافة إلى أن حجم الأعداد محدود بحجم الذاكرة التي لديك فقط ,,

و لكن المشكلة حقيقة هي في الأعداد العشرية, أعتقد أنها لا تتوفر في المكتبات الصغيرة, و لكن بكل تأكيد سوف تجدها في مكتبات أكبر و لكنها بالطبع أكثر تعقيداً,

المهم , هذه مجموعة من المكتبات التي توفر التعامل مع الأعداد الصحيحة, و غالباً تسمى هذه الأعداد Arbitrary Precision Numbers :

https://sourceforge.net/projects/cpp-bigint/

http://mattmccutchen.net/bigint/

الأولى هي الأشهر ولكني وضعت الثانية لكي تطلع عليها إذا اردت,

تحياتي ,,

#5

أنا كنت أريد أن يحاول الأعضاء القيام بذلك بأنفسهم وأنا عن نفسي قد كتبت برنامج بنفسي يحسب مضروب أي عدد :)

لكن بالنسبة لهذه المكتبة هل يمكن أن تشرح لي كيف أستخدمها فأنا لم أعرف كيف أتعامل معها اعذرني فأنا الصراحة لست متمكن في السي

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#6

السلام عليكم أخ باسم,

حسناً أعتقد أني فهمت كلامك خطأً :wacko:

سأنتظر أجابات الأعضاء, و بعد ذلك هل الممكن أن تطلعنا على كيفية فعل ذلك :rolleyes: ,

بالنسبة للمكتبة فهي موجهة لـ ++C و ليس لـ C لأنها تعرف الأعداد على أنها فئة جديدة, و يمكنك إجراء الحسابات عليها بشكل طبيعي,

هذا المثال مأخوذ من موقع المكتبة الثانية :

	#include "BigIntegerLibrary.hh"

	BigInteger a = 65536;
	cout << (a * a * a * a * a * a * a * a);

	(prints 340282366920938463463374607431768211456)

لا داعي لاستخدام دوال في العمليات الحسابية, في ++C يمكنك إعادة تعريف العمليات نفسها لتفعل ما تريد أنت!

تحياتي ,,

#7

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

اخي باسم كما قال الاخ خالد .. الحل هو باستخدام biginteger ..

وهذا الرابط اتوقع انه يفيد في الموضوع ..

http://www.codeproject.com/KB/cs/biginteger.aspx

تحياتي العطرة ..

يَارَبُ إِن ضَاقَت قُلُوُب الْنَّاسٍ عَنْ مّافِي .. مِنْ خَيْرٍٍ فَعَفْوكَ لَا يَضِيْقْ ..

#8

الكود لا يعمل يا أخ خالد ويخرج لي رسالة خطأ

'operator <<' is ambiguous

وقد قمت بتعديله إلى

#include <BigIntegerLibrary.hh>
void main()
{	
	BigInteger a = 65536;
}

فأعطاني الرسالة التالية

unresolved external symbol "public: __thiscall BigInteger::BigInteger(int)" (??0BigInteger@@QAE@H@Z)

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

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#9

السلام عليكم ,,

للأسف أخ باسم ليس لدي مترجم حالياً (جميع أجهزتي لا تعمل :lol: )

و لكن سأحاول مساعدتك قدر المستطاع بإذن الله.

أولاً ضع جميع ملفات المكتبة في المجلد الذي يوجد به ملف الكود.

ثانياً في المحرر الذي تعمل عليه, قم بتضمين ملفات المكتبة داخل مشروك,

ثالثاً, جرب الكود التالي :

#include <iostream>
#include "BigIntegerLibrary.hh"

int main()
{	
	BigInteger a = 65536;
	std::cout << (a*a);
	return 0;
}

أخبرني بالنتيجة أخ باسم :rolleyes:

تحياتي ,,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 24 يناير 2008 في 23:51

#10

هناك طريقة لإستخدام النصوص في التعبير عن الأرقام الكبيره جدا(بأي حجم) و معالجتها , مره قرأت عنها في الأسمبلي

#11
اقتباس
هذا البرنامج لا يستطيع أن يحسب مضروب 171 فأكبر مضروب يستطيع حسابه هو مضروب 170 وجرب بنفسك لتتأكد

انا جربت وهو يحسب مضروب الألف

ولكن يجب عليك تعريف متغير من نوع long double

  long double   │ 80 bits │ 3.4 * (10**-4932) to 1.1 * (10**+4932)

فهو يتعامل مع ارقام طويلة جدا

وبما انك ترد مضروب فإنه سيكون بالموجب

ماذا لو اضفت unsigned ، ليصبح unsigned long double ؟؟

ستضاعف الرقم الذي يستوعبه المتغير

#12

السلام عليكم ,,

اقتباس
هناك طريقة لإستخدام النصوص في التعبير عن الأرقام الكبيره جدا(بأي حجم) و معالجتها , مره قرأت عنها في الأسمبلي

حسناً, يمكن تنفيذ الفكرة بهذه الطريقة, و لكنها غير فعالة أبداً من حيث المساحة و المعالجة,

حيث تحتاج إلى بايت كامل لتخزين خانة واحدة (بالنظام العشري)

يعني 100 byte لتمثيل 100 خانة :blink:

بينما في الطرق المستعملة يمكنك الحصول على 100^2 عدد عشري من 100 byte فقط ;)

إضافة إلى أن المعالج مصمم ليعمل مع الأعداد بشكل تلقائي, و معالجة النصوص ستكون متعبة للمعالج, و فرق السرعة سيكون واضحاً بطريقة بشعة للغاية و خصوصاً لو أردنا حساب الـ Factorial كما في سؤال الأخ باسم,

لم أرى في حياتي حقيقة كود يمثل الأعداد الطويلة على أنها نصوص ثم يقوم بالتعامل معها, التحويل يتم فقط لعرضها على الشاشة على سبيل المثال.

هناك طرق بسيطة و أخرى جداً متقدمة, يتم تمثيل الأعداد على أنها كثيرات حدود polynomials بالنظام الثنائي,

الموضوع واسع و لا أستطيع التطرق له في رد واحد حقيقة,

تحياتي ,,

#13
abc_amjad كتب:
  long double   │ 80 bits │ 3.4 * (10**-4932) to 1.1 * (10**+4932)

وبما انك ترد مضروب فإنه سيكون بالموجب

ماذا لو اضفت unsigned ، ليصبح unsigned long double ؟؟

ستضاعف الرقم الذي يستوعبه المتغير

مسألة signed و unsigned ليست مؤثرة لأنها ستضاعف الأعداد فقط ومضروب 1000 رقم ضخم جدا

أما بالنسبة لتعريف long double فأنا لم أفهم ما الذي تقصده هل يمكن أن تعطي مثال

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

وعلى فكرة البرنامج الذي قمت به يقوم بكتابة المضروب كاملا وليس بصيغة exp كما يحدث مع double :)

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#14

هناك مكتبة في الاسمبلي تدعى BIGLIB مخصصة لعمليات الاعداد الكبيرة بالتأكيد يوجد نسخة منها للسي ... ابحث عنها ربما تفيدك !

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#15

لم اجرب المكتبات التي تتعامل مع الارقام الكبيرة

يوجد ملف في المرفقات ، انا عملته على turbo c++

0

وسأحاول عمل دوال تتعامل مع أي رقم كبير بدون تحويله لنص.

FACTORIAL.rar

#16

أخي abc_amjad برنامجك أيضا لا يحسب أكثر من مضروب 170 على العموم سأضع البرنامج الذي قمت به بعد دقائق إن شاء الله

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#17

عذرا على التأخير فقد كنت أقوم بتنسيق الكود ووضع تعليقات عليه

#include<iostream.h>
#include <stdio.h>
#include <stdlib.h>

void main()
{
	//***   Initialization   ***//
	//*** Start ***//
	int i,j,k,n;
	int NewSize=10;
	unsigned int * Factorial=NULL;
	Factorial = (unsigned int*) realloc (Factorial, NewSize * sizeof(unsigned int));
	for (i=1;i<NewSize;i++)
		Factorial=0;
	Factorial[0]=1;
	//*** End ***//

	//***   Enter Number   ***//
	//*** Start ***//
	cout<<"Enter Number   ";
	cin>>n;
	//*** End ***//

	//***   Calculation   ***//
	//*** Start ***//
	i=1;
	while (i<n)
	{
		i++;
		Factorial[0]*=i;
		j=0;
		while (j<NewSize-1)
		{
			Factorial[j+1]*=i;
			Factorial[j+1]+=Factorial[j]/100000;
			Factorial[j]-=Factorial[j]/100000*100000;
			j++;
			if (Factorial[NewSize-1]>=100000)
			{
				NewSize+=10;
				Factorial = (unsigned int*) realloc (Factorial, NewSize * sizeof(unsigned int));
				for (k=NewSize-10;k<NewSize;k++)
					Factorial[k]=0;
			}
		}

	}
	//*** End ***//

	//***   Search for the last entry   ***//
	//*** Start ***//
	k=NewSize-1;
	while (Factorial[k]==0)
		k--;
	//***   End   ***//

	//***   Print   ***//
	//*** Start ***//
	cout<<Factorial[k];
	for (i=k-1;i>=0;i--)
	{
		//***   Check if the number should have zeros in the left and print it   ***///
		//*** Start ***//
		j=100000;
		while (Factorial<j/10 && j/10>1)
		{
			cout<<0;
			j=j/10;
		}
		//*** End ***//
		cout<<Factorial;
	}
	cout<<endl;
	//***   End   ***//
}

وقد جربته على مضروب 40000 وإذا أردنا تجربة البرنامج على أعداد أكبر فيجب تغيير القيمة 100000 الموجودة في البرنامج إلى 10000 أو أقل ولكن هذا سيبطئ البرنامج

1

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#18

1000!=

[background=black]
40238726007709377354370243392300398571937486421071463254379991042993851239862902
059204420848696940480047998861019719605863166687299480855890132382966994459099742
450408707375991882362772718873251977950595099527612087497546249704360141827809464
649629105639388743788648733711918104582578364784997701247663288983595573543251318
532395846307555740911426241747434934755342864657661166779739666882029120737914385
371958824980812686783837455973174613608537953452422158659320192809087829730843139
284440328123155861103697680135730421616874760967587134831202547858932076716913244
842623613141250878020800026168315102734182797770478463586817016436502415369139828
126481021309276124489635992870511496497541990934222156683257208082133318611681155
361583654698404670897560290095053761647584772842188967964624494516076535340819890
138544248798495995331910172335555660213945039973628075013783761530712776192684903
435262520001588853514733161170210396817592151090778801939317811419454525722386554
146106289218796022383897147608850627686296714667469756291123408243920816015378088
989396451826324367161676217916890977991190375403127462228998800519544441428201218
736174599264295658174662830295557029902432415318161721046583203678690611726015878
352075151628422554026517048330422614397428693306169089796848259012545832716822645
806652676995865268227280707578139185817888965220816434834482599326604336766017699
961283186078838615027946595513115655203609398818061213855860030143569452722420634
463179746059468257310379008402443243846565724501440282188525247093519062092902313
649327349756551395872055965422874977401141334696271542284586237738753823048386568
897646192738381490014076731044664025989949022222176590433990188601856652648506179
970235619389701786004081188972991831102117122984590164192106888438712185564612496
079872290851929681937238864261483965738229112312502418664935314397013742853192664
987533721894069428143411852015801412334482801505139969429015348307764456909907315
243327828826986460278986432113908350621709500259738986355427719674282224875758676
575234422020757363056949882508796892816275384886339690995982628095612145099487170
124451646126037902930912088908694202851064018215439945715680594187274899809425474
217358240106367740459574178516082923013535808184009699637252423056085590370062427
124341690900415369010593398383577793941097002775347200000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000

االبرنامج سريع ورهيب!

ويحتاج جلسة .

شكرا لك ياباسم على هذا الكود.

tvquran_6.gif

#19

ماذا تعمل هذه الدالة بالضبط realloc ؟

tvquran_6.gif

#20
arabi2013 كتب:
ماذا تعمل هذه الدالة بالضبط realloc ؟

void *realloc(void *ptr, size_t size);

تعيد تخصيص حجم لمتغير الذاكرة المشار اليه بناء على حجم جديد معطى.

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#21

السلام عليكم,,

أخ باسم أتمنى لو كان لدي مترجم حالياً فهذا الموضوع من أحلى المواضيع في البرمجة لدي :rolleyes:

و الحقيقة هناك نقطتان :D

الأولى, بالنسبة للمكتبات, فحاول تجربة المكتبة الأولى لأنها أشهر و رأيت الكثيرين يعملون عليها.

قم بتنزيل المكتبة, هذه هي النسخة الثانية و هي أحدث نسخة حتى الآن :

bigint_2_0_src.zip

قم بتنفيذ الخطوات كما في المرة السابقة, و لكن لا تنسى أن تتأكد أن المترجم الذي لديك هو مترجم ++C و ليس مترجم C فقط, مع ملاحظة أن مترجمات ++C تستطيع ترجمة كود C غالباً و لكن العكس غير صحيح,

ثم قم بتجربة هذا الكود :

#include <iostream>
#include "bigint.h"

int main(){
	RossiBigInt x = 4000;

	for(int i = 0; i < 100; i++)
		x = x*x;
	std::cout << x;
	return 0;
}

إن شاء الله تكون التجربة الحالية ناجحة, و لا تنسى أن تخبرني بالنتائج :rolleyes:

بالنسبة للمهم و هو الأهم, هو الكود الذي وضعته,

الحقيقة نريد أن نتعلم منه و الأكثر من هذا نريد مناقشته لأن هذا النوع من الموضوعات لا يتم الكلام عنه كثيراُ حتى في المنتديات الأجنبية :D

أنا فهمت الفكرة بشكل عام و لكن نطمع أن تقوم بشرح الأجزاء التالية قليلاً :cash:

أنت تقوم بالضرب في أول عنصر بالمصفوفة ثم إزاحة العدد للعناصر التالية, بالطبع عن طريق إزاحة الخانات,

ماهو الشيء الذي يحصل هنا تحديداُ :

Factorial[j+1]*=i;
			Factorial[j+1]+=Factorial[j]/100000;
			Factorial[j]-=Factorial[j]/100000*100000;

بالنسبة لمعرفة العناصر الفارغة في المصفوفة فهو جميل و واضح B)

	//***   Search for the last entry   ***//
	//*** Start ***//
	k=NewSize-1;
	while (Factorial[k]==0)
		k--;
	//***   End   ***//

تحياتي أخ باسم,

#22

بالنسبة لكودك يا أخ خالد فقد أعطاني هذا الخطأ

cannot convert from 'const int' to 'class RossiBigInt'

وعندما نظرت في ملف bigint.h وجدت أن RossiBigInt عبارة عن Class

وسأقوم بشرح الجزء الذي سألت عنه قريبا إن شاء الله

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#23

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

أولا سنفترض أن كل خانة ستحوي الأعداد من 0 وحتى 9

ونريد الآن حساب 234*6

4 3 2

6

ـــــــــــ

سنقوم أولا بضرب 6*4 فيكون الناتج 24 أي 4+20 طبعا سنضع في هذه الخانة 4 ونحول 20 من الخانة الأولى إلى الخانة الثانية بقيمة 2 ولكن بعد ضرب الخانة الثانية في 6

6*3+2=20=0+20 الآن سنضع في هذه الخانة 0 ونحول 20 أيضا إلى الخانة التالية بقيمة 2

6*2+2=14 سنضع في هذه الخانة 4 ونحول 1 إلى الخانة التالية

6*0+1=1 وبذلك نكون قد انتهينا والناتج هو 1404

طبعا هذا الكلام واضح ومفهوم وكلنا قمنا بذلك مرارا وتكرارا في المرحلة الإبتدائية

أنا كل ما قمت به في الكود الخاص بي أني جعلت قيمة الخانة تساوي 100000 أو مائة ألف بدلا من 10 لأقلل عدد الخانات المستهلكة وبالتالي أقلل من عدد مرات الضرب وحتى أستغل أكبر قدر ممكن من المساحة المتاحة في المتغير من نوع Integer

ممكن تطبيق هذا الأمر على العملية السابقة في حالة جعلنا قيمة الخانة بـ 100 كالتالي

34 02

6

____

سنقوم بالآتي

6*34=204=04+200 سنضع في هذه الخانة القيمة 04 ونحول 200 إلى الخانة الثانية بقيمة 2

6*02+2=14 وبذلك نكون قد انتهينا في عدد أقل من الخطوات والناتج هو 1404

المشكلة أن القيمة 04 سيتم تخزينها 4 بدون 0 لأن الصفر على اليسار غير مؤثر لكن في حالتنا هذه فإن الصفر له نفس أهمية الـ 4 ولا يمكن تجاوزه أبدا لذلك كتبت ذلك الكود عند الطباعة

//***   Check if the number should have zeros in the left and print it   ***///
//*** Start ***//
j=100000;
while (Factorial<j/10 && j/10>1)
{
	cout<<0;
	j=j/10;
}
//*** End ***//

لإختبار عدد خانات الرقم وإضافة أصفار على اليسار بقد الحاجة

أخيرا نحن نعلم أن أقصى قيمة يمكن وضعها في unsigned int هي 4 مليار تقريبا لذلك إذا قمنا بحساب مضروب 40 ألف مثلا وكانت إحدى الخانات بها 99999 فسيقوم البرنامج بالآتي

99999*40000 تساوي تقريبا 4 مليار وبالتالي لن يكون هناك مشكلة لكن ماذا لو أردنا حساب مضروب 45 ألف مثلا

سيقوم البرنامج بحساب

99999*45000 وهي تساوي 4.5 مليار تقريبا وهذا أكبر من الحد المسموح به في unsigned int وبالتالي فسيكون الناتج النهائي خطأ تماما

وللتغلب على هذه المشكلة يمكن جعل قيمة الخانة 10 آلاف بدلا من 100 ألف فنستطيع بذلك حساب حتى مضروب 400 ألف وهكذا

لكن بالطبع تقليص قيمة الخانة يعني استهلاك عدد خانات أكبر أي مساحة ذاكرة أكبر وأيضا يعني عمليات ضرب أكثر وسيؤدي بالتالي إلى تقليص سرعة البرنامج

وعلى فكرة هذا الكود على ما هو عليه الآن يقوم بحساب مضروب 40000 أسرع من الآلة الحاسبة الموجودة مع الويندوز ولكن بفارق ضئيل :)

وبالنسبة لكو الطباعة يمكن تعديله طبعا ليطبع الأعداد بالدقة التي نريد كالآتي

//***   Print   ***//
//*** Start ***//
cout<<Factorial[k]<<".";
for (i=k-1;i>=k-10;i--)
{
	//***   Check if the number should have zeros in the left and print it   ***///
	//*** Start ***//
	j=100000;
	while (Factorial<j/10 && j/10>1)
	{
		cout<<0;
		j=j/10;
	}
	//*** End ***//
	cout<<Factorial;
}
cout<<"e+"<<k*5;
cout<<endl;
//***   End   ***//

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#24

السلام عليكم أخ باسم,,

شرحك جميل, و سأحاول تطبيق الفكرة عندما أحصل على مترجم في أقرب فرصة B)

بالنسبة للخطأ الذي ظهر لك فهو خطأ غبي لم أنتبه له حقيقة :D

كل ما عليك هو تجربة التالي :

#include <iostream>
#include "bigint.h"

int main(){
	unsigned long y = 4000;
	RossiBigInt x = y;

	for(int i = 0; i < 100; i++)
		x = x*x;
	std::cout << x;
	return 0;
}

أو أن تقوم بتحويل العدد إلى النوع unsigned long مباشرة عن طريق الـ casting كالتالي :

[code]#include <iostream>
#include "bigint.h"

int main(){
	RossiBigInt x = static_cast<unsigned long>(4000);

	for(int i = 0; i < 100; i++)
		x = x*x;
	std::cout << x;
	return 0;
}

طبعاً السبب ليس مهماً كثيراً و لكن ببساطة الـ constructor الخاص بالـ RossiBigInt معرف كالتالي :

typedef unsigned long ulong;
	explicit RossiBigInt (ulong unit_i);

طبعاً المترجم يجب أن يقوم بتحويل العدد إلى النوع ulong بشكل طبيعي, و لكن بسبب الـ explicit أصبح ذلك غير صحيح,

لأن المترجم سيقوم بتحويل العدد إلى النوع الافتراضي و هو int :D

و سيظهر الخطأ الذي كتبته.

تحياتي ,,,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 27 يناير 2008 في 05:22

#25

عايز أضيف نقطة مالهاش علاقة بالموضوع أوى :)

أحلى و أقوى و أنضف مكتبة لل huge numbers هى gmp بلا منازع > http://gmplib.org/

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

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