ماذا عن الارقام الضخمة وطريقة تخزينها فى المتغيرات

مرحبا , انا اتعلم البرمجة , البداية الحقيقية مع c/c++

والطبع اعمل على المشاريع الصغير جدا

مثل عمل اله حاسبة وبرنامج يسأل عن العمر وما الى ذلك ,

ولكن لدى سؤال هنا ,

نحن نحفظ البيانات هذه فى المتغيرات

int,float...etc

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

وبالتالى حجم معين من البيانات تحفظها هذه المتغيرات

اذا ماذا لو ادرت برنامج يحسب عمر جميع البشر الاحياء على وجه الارض

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

فكيف استطيع ان اجعل البرنامج غير محدود فى تلك النقطة

مثال اخر لتظهر الفكرة اكثر

الالة الحاسبة البسيطة التى ينشأئها كل من يبدأ فى تعلم البرمجة

ينشأ ثلاثة متغيرات

يطلب من المستخدم ادخل قيمة الاول والثانى بيقوم البرنامج بجمعهم ويخزن المجموع فى الثالث : ماذا لو كتب المستخدم عدد مكون من الاف الارقام

مثل هذا

999999999999999999999999999999999999999999999999999999

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

شكرا مقدما

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

التعليقات

وفقا لل C99 standard

طول متحول من نوع unsigned long long int

تكون 64-bit

بالعشري تعطي 18446744073709551616

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

المكتبة stdint.h

اسم المتحول uint64_t

unsigned long long (8 bytes) 0 to 18,446,744,073,709,551,615

ولكن ما تبحث عنه انت يمكن حله بعدة طرق ...

أولا بشكل رياضي .

وذالك يعتمد على مقدار الدقة المطلوبة و استخدام الرياضيات قبل الكود البرمجي

فمثلا الرقم الذي كتبته انت

999999999999999999999999999999999999999999999999999999

يمكن تمثيله رياضيا ب

999*10^45

وهنا الدقة 1 بالالف

اذا كنت تحتاج الى دقة 1 بالمليون يتم تمثيل الرقم

999999*10^42

وهكذا ....

ثانيا :

يمكنك تقسيم الرقم في مصفوفة ... كل رقم عشري يتم تخذينه في خانة بقلب المصفوفة أي من 0 الى 9

و يتم الجمع كل خانة على حدى ثم القيام باختبار اذا تجاوزت قيمة ناتج الجمع رقم 9 ... اضافة واحد للخانة اللاحقة في المصفوفة " و التي تمثل الخانة العشرية التالية "

طبعا هذا مجرد مثال ويمكن عمليا تطبيق الفكرة كل 18 خانة عشرية

مزيد من المعلومات عن انواع المتغيرات في هذه المقالة

xlmnxp أضف ردا

العكس ليس:

999*10^45

بل

999*(10^45)

شكرا ..

حاولت الكتابة من اليسار لليمين ولكن الرقم ظهر من اليمين ؟؟؟

الان انتبهت أننا نحتاج الى 5 مسافات قبل السطر

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

حدود ؟ كيف للمعالج حدود فى الجمع والطرح ؟

تقصد انه سيأخذ وقت اطول قى حساب الاعداد الضخمة ؟

بالعشري تعطي 18446744073709551616

هذا العدد مكون من 20 رقم

ماذا لو اراد المستخدم جمع عدد على عدد وكل عدد مكون من 30 رقم ؟

وذالك يعتمد على مقدار الدقة المطلوبة و استخدام الرياضيات قبل الكود البرمجي

هل هذا يعنى اننى يجب ان اكون على علم بالاعداد التى سيأخذها البرنامج ؟

ولكن لا استطيع ان اتوقع ما هى كل الاحتمالات التى سيكتبها المستخدم , ماذا لو اراد جمع عدد حبات التراب فى كوكب الارض ثم جمعها على عدد حبات تراب الكوكب الاحمر الشقيق ابن العم (المريخ) :

الارقام ستكون ضخمة بشدة وقتها

يمكنك تقسيم الرقم في مصفوفة المصفوفة ايضا لها حدود فى عدد الخانات

تبقي نفس المشكلة هنا

وهى انى انشأت مصفوفة بعدد 100 خانة

كيف اضمن ان لا يدخل المستخدم 101 رقم فى العدد ؟

بقلب المصفوفة

خارج الموضوع كان لدى برنامج صغير لديه طرق حل عادية ولكنها طويلة

فكرة قلب المصفوفة كان حل عبقرى لدى لنهاء البرنامج بدقة اعلى وكود اقل بكثير

ولكنى لم استطيع تنفيذها , اتمني ان اصل الى طريقة تنفيذها قبل انفجار النبضة الكهرومغناطيسية على كوكب الارض ههه

kikoknkn أضف ردا

بخصوص نقطة حدود المعالج ... ما كنت اقصده هي طول الكلمة للمعالج

مثلا معالج

The Z80 CPU is an 8-bit based microprocessor

وهو أول معالج درسته بالجامعة .... منذ 10 اعوام

لاحظ أن طول الكلمة هو 8-bit و يتم الجمع بلغة الاسمبلي كالتالي

خلال دورة زمنية واحدة تستطيع ارسال أول قيمة "كلمة 8-bit"

خلال دورة زمنية ثانية ترسل ثاني قيمة "كلمة 8-bit"

خلال دورة زمنية التالية نرسل اشارة الجمع add

خلال دورة زمنية نحصل على الجواب "كلمة 8-bit" واذا كان الجواب اطول من 8 يرسل المعالج اشارة لوجود فائض

ولتنفيذ عملية جمع لارقام اكبر تحتاج لتجزيء العملية ثم تكرار الخطوات السابقة ... وهكذا

اذا المعالج محدود بطول الكلمة ... ولكن المبرمج هو من يجعل الحلول غير محدودة ...

وبالمناسبة معالج z80 لا يستطيع تنفيذ عملية الضرب ...

نصيحة : اقضي بعض ساعات في كتابة وتجربة برنامج جمع للمعالج z80

وبخصوص سؤالك

هل هذا يعنى اننى يجب ان اكون على علم بالاعداد التى سيأخذها البرنامج ؟

طبعا يجب تحديد المجال المقبول للادخال و اختباره

فمن الاسلم اظهار رسالة ادخال خاطء للمستخدم... من انهيار البرنامج

حتى الالات الحاسبة التجارية مثل كاسيو casio يكتبو في كتاب الاستخدام معلومتان وهي المجال و الدقة

راجع الملف التالي ابتداء من الصفحة 31

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

هناك نوع متغير long

ايضا له محدودية فى الذاكرة :

راجع هذا الرابط

اذا يبقي السؤال , ماذا لو اردنا جمع عدد مكون من مليون رقم مثلا ؟

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

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

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

اذا لغة السي ليست مثل البايثون افتراضيا !

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

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

ربما هنا فعلا سبب للتفكير فى التغير بين اللغات حيث لكل واحدة ميزة معينة

wgh أضف ردا

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