أريد عمل data type كبيرة جدا أستطيع أن أحدد مساحتها بنفسي , لانني أريد عمل برنامج على السي بلس بلس يقوم بحساب !(1000) , مضروب الألف
أريد عمل data type كبيرة جدا أستطيع أن أحدد مساحتها بنفسي
لغة ال C++ تمكنك من اعطاء data type مثل Long or float قيمة كبيرة جدا... على حسب ما اعتقد لذلك لا داعي ل data type جديد
راكان الحنيطي
Be Open Source

السلام عليكم
1000!=4.02387260077093773543702433923e+2567
العدد يتكون من 2597 رقم
السؤال الاول: هل يوجد Data type يستطيع ان يحمل كل هذا الرقم؟
السؤال الثاني : كم ستستغرق العمليه الحسابيه.
مازلت افكر فى الامر.
والسلام
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
السلام عليكم ,,
نحتاج في حالات كهذه لأنشاء class جديد كليا ليتعامل مع هذه الأرقام الضخمة جدا ,,
من الطرق المستخدمة ,, هي أن تعامل الأرقام كسلسلة من الأحرف والفكرة بشكل سريع كالتالي ,,
بالطبع الرقم نحتاجه لكي نقوم عليه بعمليات ضرب وطرح وجمع وقسمة ,, عندما نجمع رقمين ,, فيمكننا بالطبع أن نتوقع حجم الرقم المجموع هل هو بنفس عدد خانات أكبر رقم من الرقمين المجموعين أم يزيد بواحد ,, وكذلك في الضرب وكذلك في الضرب ,,
الكمبيوتر لم يخلق الا ليحاكي الواقع ويستفيد منه الناس في أعمالهم اليومية ,, لذا أفضل الطرق على الاطلاق لمعرفة حل مشكلة ما هن أن نقوم بمحاكاتها ,,
فعليك لحل مشكلة كهذه أن تأتي بورقة وقلم وتجلس بعيدا عن الكمبيوتر وتفكر وتحاول أن تقوم بعدة عمليات جمع تقليدية بين رقمين كبيرين مثلا ,,
12345334444432
+
243542244322
بالطبع سنجمع بنفس الطريقة التقليدية القديمة في الجمع " بالنسبة لهذه الخوارزمية " ,, سنجمع كل عددين متقابلين ونضع المجموع في خانة الرقم الجديد الناتج ,, واذا كان أكبر من 10 لكل خانة سنضع خانة الآحاد ونزيد الخانة التي تليها واحد ,, وهكذا ,,
بهذه الطريقة يمكنك أن تتخيل الفئة الجديدة على النحو التالي :
BigNum result,num1,num2;
num.PutData("3354353277667545434");
num2.PutData("3435325356646");
num.Add(num1,num2);الدالة Add مثلا ستقوم بانشاء سلسلة char خالية بحجم أكبر رقم + 1 احتياطا ,, لأن المجموع ممكن أن يزيد خانة اضافية من أكبر رقم ,,
بالطبع ستنشيء في نفس الفئة دالة لاستخلاص الرقم الموجود في كل خانة char بعمل مقارنة أو باستخدام جدول الآسكي ,,
وبعد ماتستخرج الرقم الموجود في كل خانة تقوم بالعملية الأحادية بشكل مباشر ,,
توجد طرق أخرى بالطبع باستخدام البتات بحيث نخزن العدد في أكثر من جزء int مثلا أو حتى في سلسلة char أيضا ,, الأفكار كثيرة في هذا الصدد ,,
لكن أنصحك أن تبدأ بطريقة الأولى التي ذكرتها لك فهي الأسهل ,,
وان احتجت للمزيد من المعلومات فاسأل وسنساعدك باذن الله ,,
نسيت أن أقول ,,
الأعداد float مثلا هي عبارة عن أعداد 32 بت فقط عائمة ,,
الاعداد int أعداد 32 بت أيضا فأكبر عدد يمكن تمثيله من
unsigned int هو 2 أس 32 وهو العدد 4294967296 ,,
الأعداد Long int و Long double هي أعداد ذات 64 بت أي أن أكبر عدد يمكن تمثيله بالنسبة للأعداد الصحيحة فيها هو 2 أس 64 :
18446744073709551616
وتوجد أعداد جهازة ذات 64 بت مع مصرف الفيجوال سي وأغلب المصرفات الأخرى أيضا ,, وفي ال Viual C++ توجد الأعداد INT64 ,,
لكن لايمكن تبني مثلا هذه الأرقام الصغيرة جدا بالنسبة لمضروب ال 1000 مثلا ,, ولا الأرقام التي أكبر من ذلك ,, لذا يجب التفكير بانشاء خوارزمية جديدة كليا ,,
بالنسبة للزمن في عملية جمع عددين بطول 5000 خانة لكل منهما فستأخذ وقت يسيرا جدا ,, لأن الأمر لايعدو كونه عملية جمع 5000 مرة مع استخلاص العدد من ال char فقط ,,
بالنسبة لضرب عددين 5000 خانة في 5000 خانة أيضا ,, فالناتج سيكون أكبر مايكون بطول 10000 خانة + 1 ,,
عملية الضرب في هذه الأعداد ستتم 5000 * 5000 مرة حيث كل خانة من الرقم الأول ستضرب 5000 مرة في كل خانات العدد الثاني ,, وهكذا ,,
مع عمليات جمع داخلية أيضا ,, مما سيستهلك وقتا لاأستطيع تقديره الا بالتجربة والخطأ أو محاولة محاكاة زمن تنفيذ تعليمة أو عدة تعليمات أسمبلي ومعرفة العدد الكلي للتعليمات ومعرفة الزمن من ذلك ,,
في مصرف الفيجوال سي++ توجد أداة لمعرفة أداء برنامج ما ويعطيك المصرف نتائج بالجزء من الألف من الثانية لك سطر برمجي في الكود ,,
يمكن أن تفيد في تحديد شيء كهذا ,, عموما كتبت فئة كالتي نتحدث عنها من قبل ,, لكن منذ مدة ولا أذكر بالتحديد الزمن المستغرق لأداء المهام ,,
لكن بالنسبة للأعداد حتى 100 خانة تقريبا في معالج 1700 MHz كانت تنفذ بسرعة كبيرة ,, ولم أجرب مطلقا الأعداد الأكبر من ذلك ,,
بارك الله فيكم ,,
السلام عليكم
الاخ HGB الفرق بين مضروب 100 و مضروب 101 كبير جداً , مضروب 101= 101*مضروب 100, فما بالك بمضروب 1000. اعتقد ان مضروب 1000 ياخذ وقت اكبر بكثير من مضروب 100.
هناك مكتبه خاصه بمثل هذه الاعداد الكبيره تدعى GMP (GNU Multiple Precision Arithmetic Library) وموجوده على هذا الرابط:
يمكنك عمل include للمكتبه ومن ثم إستخدام احجام كبيره جداً من الارقام.
والسلام
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
إخواني في الله
المشكلة الرئيسية في هذا البرنامج هي كيف نستطيع ان نعمل data type نحدد
مساحتها كيف نشاء , هذا على حسب معلوماتي المحدودة .
والله أعلم
السلام عليكم
نعم اخى هذه فقط احدى المشاكل, المشكله الثانيه التى ستواجهك هى كيف تقوم بعمليات حسابيه لهذا ال data type, والمشكله الاخيره هى عامل الزمن حيث ان مثل هذه العمليه تزيد تعقيداً كلما كبر الرقم.
الرابط الذى وضعته فيه مكتبه تحل المشكله بستخدام ال FPU Floting point unit. والتى تقوم بمثل هذه العمليات الحسابيه بشكل افضل من ال CPU .
والسلام
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
شكرا لك أخي الكريم على اهتمامك بالموضوع .
لقد دخلت على الرابط الذي وضعته ولم أفهم فيه أي شيء .
وهل هذا البرنامج مستحيل على السي بلس بلس ؟؟؟
ليس مستحيل ولكن معقد, المشكله غالباً تكمن فى عامل الوقت.
لا اظن ان إستخدام المكتبه صعب, كل ما عليك عمله هو :
#include <gmp.h>
ثم إختيار ال data type الذى يتناسب مع إحتياجاتك.
والسلام
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
السلام عليكم ,,
الملفات مضغوطة بصيغة tar gz وهي خاصة بنظام التشغيل Linux و Unix وصاحب الموضوع وضعها أصلا لل FreeBsd ,,
لكن يمكن فك ضغطها بال WinZip كما ذكر في مكان آخر ,, لذا عليك أن تحاول ,, وسأنزلها أنا لاحقا ,,
لكن السؤال هل تريد استخدام مكتبة أم تريد كتابة مكتبة خاصة بك ؟
اذا كنت تريد استعمالها فحسب ,, فلاداعي لاختراع العجلة مرة أخرى ,,
أما اذا أردت كتابة مكتبة جديدة كليا خاصة بك ,, فعليك بالتدرج رويدا رويدا ,,
مثلا المكتبة التي وجدها أخونا غريب حفظه الله,, تستخدم في تخزين الأعداد Words كاملة وكما ذكر صاحبها Full Word ,, المهم بعرض 16 بت لكل منها أي مثل ال short ,,
لكن الحبكة في خوارزمية التعامل مع الضرب والقسمة والطرح والجمع ,, وأؤكد لك أنك لو سعيت في هذا الأمر مدة من الزمن يمكنك انتاج مكتبة مستواها ولو 3 أرباع أداء هذه المكتبة ,, لكن أؤكد لك أن ستمزق نصف شعرك وأنت تحاول في هذا الأمر ,,
لذا اذا أردت أن تبدأ فابدأ بالأسهل وهو حل ال char الذي ذكرته لك في البداية,, ثم بعدها عليك ان تفكر بنفسك في طريقة أخرى :)
ولاتخشى شيئا لو أردت حساب مضروب ال 100 ولا حتى ال 101 لأن الفرق بينهما مجرد عملية ضرب 200 خانة كل خانة في خانتين وستكون سريعة جدا بالنسبة لمعالجات ال 2 جيجاهيرتز ,, لكن لو قلت الفرق بين ال 500 وال 501 فهو كبير فعلا وبعد ذلك تصبح التضخمات غير محتملة ,,
ويمكن لخوارزمية اصحابنا أصحاب المكتبة نفسها ان تستسلم أمام 10000 أس 10000 ,,
لذا عليك بالتجارب !!
حظا ممتعا ,,
السلام عليكم
هنا تجد المكتبه بصيغة .zip معى شرح لكيفية الإستعمال.
والسلام
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
اسف نسيت احط الرابط, جل من لا يسهو
تم تعديل هذه المشاركة بواسطة احمد غريب في 30 أبريل 2004 في 23:37
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
السلام عليكم .
اسمحو لي ان اشارككم في هذا الحوار.
كما ذكر الاخ HGB بوجود طريقة لتعريف انواع جديدة باستخدام فئات C++ تتنكر كانها نوع جديد.
ويوجد مثال جميل في كتاب " ++C الدليل الكامل" لحل هذه المشكلة . تحت اسم verylong ويمكن استخدامة كنوع جديد من البيانات ( اجرا عمليات الضرب والجمع عليه كما في الانواع الاخري )
ولكن المشكلة في هذا المثال هو استخدام سلاسل من الحروف (char) لتمثيل الاعداد
مما يسبب البطء الشديد في المعالجة !!
والسؤال هو هل توجد طريقة بنفس هذه الطريقة ولكن باستخدام مصفوفة من int مثلاً.
وشكراً.
تم تعديل هذه المشاركة بواسطة زيدان في 1 مايو 2004 في 05:03
أخي الكريم / زيدان
شكرا لك على مشاركتك في هذا الحوار .
لكن هل هذا الكتاب المذكور موجود على الانترنت ؟
ام انني يجب ان ابحث عنه في المكتبة ؟
وشكرا ,,,
السلام عليكم / أعتقد يامشرفنا الكريم أن الموضوع وحماسك على المشاركة في
هذا الموضوع أنســــــاك وبصراحــــة ان تتنتقي بعض ألفاضك بعناية وهي إن شاء الله
أن تكون هفوه غير مقصودة لي كني التحية ....... الكمبيوتر لم يخلق ........
@@@@ أخوكم / أبو عبدالرحمن @@@
بارك الله فيك أخي khalid_c ,,
لكن الكمبيوتر من مخلوقات الله التي خلقها من العدم أيضا ,, لأن الله خلق من صنعها من العدم ,,
فالكمبيوتر لم يخلق فعلا الا ليحاكي الواقع :)
تم تعديل هذه المشاركة بواسطة HGB في 4 مايو 2004 في 03:36
السلام عليكم.
انا أسف على التأخير .
لأنني لم أكن أعرف ان الردود يمكن ان تكون على أكثر من صفحة.
المهم .
الكتاب يا أخي بالله . موجود على موقع الناشر باللغة العربية :
www.asp.com.lb/catalog/books/bookpage.asp?id=75853
وهو مترجم الى اللغة العربية بشكل احترافي وجميل.
اما إذا اردت نسخة انجليزية
ابحث عن C++ Interactive Course: Fast Mastery of C
وهو موجود في موقع " أمازون "
www.amazon.com/exec/obidos/tg/detail/-/1571690638/103-8863299-4941407?v=glance
أما إذا اردت المثال فقط , أخبرني وسوف أقوم بكتابته كاملاً لك.
ملاحظة: إذا لم يعمل الرابط قم بنسخه ثم لصقه في خانة العنوان للمتصفح . وشكراً
تم تعديل هذه المشاركة بواسطة زيدان في 4 مايو 2004 في 04:07
ألف شكر ليك يا أخي / زيدان (المحترم)
على اهتمامك بالموضوع , والموقع الجميل هذا .
وبصراحة يا أخي إذا تكرمت أن تكتب لي هذا البرنامج المعقد وتبعثه لي على الايميل الخاص بي وهو : mido989@gnmail.com أو mohedsabri@hotmail.com
ولك مني خالص الحب والاحترام / محمد صبري
السلام عليكم
إليكم الحل النظرى لمشكلة مضروب الاعداد الكبيره.
بستخدام اللوغارتمات نستطيع كتابة الرقم على النحو التالى:
log(1000!)=log 1000 +log 999+...+log1
العدد الناتج سيكون
log(1000!)=2567.6046442221328487714230578045
الان يمكننا ان نحفظ الرقم 2567 فى متغير, ثم نقوم بحساب:
10^0.6046442221328487714230578045
والذى يسوى:
4.0238726007709377354370243392236
هذى الاخر يمكن حفظه فى متغير من نوع float , و إذا إستخدمنا FPU لن تستغرق العمليه الحسابيه وقت طويل,,
الان لدينا رقمين, احدهما عدد صحيح والاخر عدد عشرى, وبذالك نستطيع كتابة الرقم المطلوب على النحو التالى:
4.0238726007709377354370243392236 E2567
والسلام
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
أخي الكريم / أحمد غريب
ولكن كيف لنا أن نتكتب حساب مضروب الاعداد الكبيرة على هيئة برنامج ++C .
وشكرا ,,,,,,,
السلام عليكم
اخى الحبيب انا لست خبير c++ ولكن الفكره العامه هى كتالى:
flout res1=0; float res2=0; cin << Nr; for(int i=0;i<Nr;i++) res1=res1+LOG(i); res2=EXP(FRAC(res1); cout <<Nr<<"! = "<<res2<<"10^"<<(int)res1;
FRAC تقوم بإزالت الرقم الصحيح من العدد, EXP تقوم برفع العدد على عشره.
ارجو ان تكون الفكره واضحه
والسلام
تم تعديل هذه المشاركة بواسطة احمد غريب في 4 مايو 2004 في 23:55
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
السلام عليكم ,,
مشكورين جدا ياخبيرنا أحمد على هذه الطريقة الجميلة ,,
لكن نطلب منك اذا تكرمت وكان لديك ولو متسعا من الوقت ,, أن نتعرفنا فقط على كيفية تخزين الارقام العائمة من قبل الجهاز ,,
لأن تخزين رقم ك : 4.0238726007709377354370243392236 في 4 بايت لهو محير حقا !! لم أبحث في الأمر لكن أتوقع أن الكمبيوتر يقوم بتخزين عواملها الأولية ويولد الرقم وقت الطلب ,, هل هذا مايحدث :huh:
وشكرا لك على وقتك :)
السلام عليكم
حيا الله مشرفنا الحبيب, بالطبع لن تحصل على الرقم 4.0238726007709377354370243392236 إذا إستخدمت ال FPU ولكن سيقوم ال FPU بعملية trunc او round للعدد العشرى, هناك 3 data type تستخدم للاعداد العشريه, وهي على النحو التالى.
Single Precision (32-bit) Floating Point Format 32bit=seeeeeeee1mmmmmmmmmmmmmmmmmmmmmmm 64-Bit Double Precision Floating Point Format 64bit=s(11*e)1(51*m) 80-bit Extended Precision Floating Point Format 80bit=s(14*e)1(63*m)
s هى لل sign وال e للعدد المرفوع على العشره و ال m تسمى matissa وهى العدد العشرى نفسه, ال 80bit هى للعمليات الحسابيه فى البروسسور فقط لتعطيك حسابات ادق ولكن عند التخرين يقوم البروسسور بتحويل الرقم الى 64bit والتى تعطى الحل بدقة 13 رقم .ال FPU يستخدم طريقة ال IEEE فى حساب الاعداد العشربه إذا اردت معرفة المزيد عليك بزيارة الموقع التالى :
http://research.microsoft.com/~hollasch/cg.../ieeefloat.html
هناك حل اخر للمسئله ولكنه اصعب من الاول, وهو بإستخدام Stirling numbers , ساقوم بالبحث فى هذا الامر ثم اعود بالخبر اليقين بعون الله.
والسلام
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
هذا الموضوع مغلق.
