فى الموضوع أسئلة الإحماء لبداية مسابقات القسم قام الأخ ghost بوضع اختبار لعمل اله حاسبه تحتوى على العمليات الحسابيه البسيطه و الأقواس، و حيث ان اضافة الأقواس يجعل تحليل العمليه الحسابيه معقد قليلا لذا انا قلت
اقتباسو تعقيد بتعقيد نقوم بإضافة بعض الدوال الرياضيه مثل abs و floor و ceil و sin و cos و tan.
طبعا انا لم اكتفى بهذا و لكنى رأيت انه من الجميل انك لو تستطيع كتابة الأرقام بصيغ غير العشريه ايضا، بمعنى انك يمكنك كتابة معدله تقوم فيها بجمع رقمين احداهما ثنائى و الأخر ثمانى و الناتج يظهر سداسى عشرى او اى نوع اخر. لذا فقد شرعت فى التنفيذ و الحمد لله انى انتهيت منها.
هذا الدرس مخصص لشرح كيفية برمجة الأله الحاسبه و كيف قمت بعمل الـ Parser الخاص بها.

داخل هذه الأله قمت بإستخدام طريقتين لتحليل المعادله التى يدخلها المستخدم:
- استخدام VB.Net Compiler لمعرفة ناتج العمليه
- استخدام Custom Parser لمعرفة ناتج العمليه
سأقوم فى البدايه بشرح الـ Custom Parser يليها شرح كيفية استخدام VB.Net Compiler.
يتكون الـ Parser من مجموعه من الدوال شكلها كالتالى:
Imports System.Reflection Public Class Functional Shared Sub New() Public Shared Property OutputStyle() As NumberSystem Public Shared Property FormatBinary() As Boolean Public Shared Function Eval(ByVal value As String) As String Private Shared Function CalcExpression(ByVal value As String) As String Private Shared Function CalcTerm(ByRef value As String, ByRef index As Integer) As Decimal Private Shared Function CalcNumber(ByRef value As String, ByRef index As Integer) As Decimal Private Shared Sub NumbersToNativeForm(ByRef value As String) Private Shared Function FunctionsInExpression(ByVal value As String, ByRef names() As String) As Integer Private Shared Sub FilterFunctions(ByRef value As String) Private Shared Function CountOf(ByVal search_for As String, ByVal value As String, ByVal start_index As Integer) As Integer Private Shared Function CountOfAll(ByVal search_for() As String, ByVal value As String) As Integer Private Shared Function FindBestFitFunction(ByRef fnNames() As String, ByVal value As String, ByVal start_index As Integer, ByVal end_index As Integer) As String End Class
اولا اسم الفئه هو Functional و الهدف من هذا الإسم هو انى كنت اصنع هذه الأله الحاسبه بثلاث طرق اولهما بإستخدام VB Compiler و الاخرى بإستخدام مجموعه من الدوال اما الأخيره فبإستخدام مجموعه من الفئات لذا فقد قمت بتسمية الفئه الخاصه بالدوال Functional.
لتحليل المعادله المدخله من المستخدم اقوم بالخطوات التاليه:
- قم بحذف المسافات من المعادله.
- قم بوضع قوس البدايه و النهايه للمعادله (و هما القوسين"()").
- قم بالبحث عن اى ارقام غير عشريه و قم بتحويلها للنظام العشرى و ابدال الموجود بالنسخه العشريه.
- قم بتحليل المعادلات و ابدالها بناتجها.
- قم بتحليل الأرقام الباقيه و التى فى الأغلب لن تكون إلا بعض الأرقام و العلامات الرياضيه البسيطه (+ ، - ، * ، /)
- قم بإظهار الناتج
ملحوظه : فكرة تحليل المعادله التى تحتوى على العلامات الحسابيه من كتاب Begining Visual C++ 2005 لـ Ivor Horton.
فى البدايه لابد من فهم كيفية تحليل معادله بسيطه تحتوى فقط على العلامات الرياضيه و كذلك الأرقام فقط.
يقوم المستخدم بإدخال معادله مثل
و كما تلاحظ فقد وضع بها مسافة (المربع الثانى الفارغ) و حيث ان المسافه لا هى رقم و لاهى علامه رياضيه فبالتالى واجب حذفها لتصبح المعادله بالشكل التالى:
تحتوى المعادله السابقه على جميع العلامات الرياضيه و حيث انه من البديهى ان الضرب و القسمه لهما الأولويه الاولى و الجمع و الطرح لهما الترتيب الثانى لذا سنحتاج لتعريف بعض المصطلحات:
expression : و هى المعادله نفسها
term: و تمثل رقم او رقمين بينهما علامة الضرب او القسمه او مجموعه من الأرقام و يأتى بينهم علامات الضرب و القسمه فقط.
operator: و هى علامة الجمع او الطرح.
و بالتالى يمكن القول ان المعادله تحتوى على مجموعه من الـ terms و الـ operator و التى دائما ما تاخذ الشكل التالى:
expression = term operator term operator ........ term
الشكل التالى يوضح المعنى بشكل افضل
و السؤال الذى يتبادر إلى الذهن هو ماذا يحدث عند وجود رقم مكون من اكثر من خانه؟
فى هذه الحاله سيتم تقسيم الرقم الموجود بالـ term إلى مجموعه من الـ digits كما فى الصوره التاليه
كما ترى من الصوره تم الرمز إلى علامة الضرب و القسمه بـ multop اى (multiplication operator) و الجمع و الطرح بـ addop أى (addition operator)، ايضا تم تقسم الرقم الواحد إلى مجموعه من الـ digits.
مما سبق نجد اننا يمكننا عمل التالى:
- ابحث عن مكان اول علامة جمع او طرح. (لذا مما عرفناه سابقا سيكون ما قبل علامة الجمع و الطرح هو term).
- لدينا الأن term نقوم بتخزين كل ما يقابلنا داخل متغير رقمى حتى نقابل علامة الضرب او القسمه فإن وجد سيكون لدينا حاله من اثنين
- إما ان التالى هو رقم لذا سنقوم بتخزينه فإن قابلنا علامه جديده سنقوم بتطبيق العلامه التى من 2 على هذا الرقم مع الذى قبله ثم نبدأ من من هذا المكان 2.
- و إما اننا وصلنا لمكان علامة الجمع و الطرح لذا سنستبدل حتى هذا المكان بالرقم النهائى و نعود لرقم 1.
الأن عرفنا كيف سنقوم بتحليل الـ Expression و لكن كيف سنقوم بتطبيق هذا الكلام برمجيا
داخل الفئه Functional توجد 3 دوال وهم
Private Shared Function CalcTerm(ByRef value As String, ByRef index As Integer) As Decimal
Private Shared Function CalcNumber(ByRef value As String, ByRef index As Integer) As Decimal
Private Shared Function CalcExpression(ByVal value As String) As String
البدايه تكون مع الداله CalcExpression و التى تستقبل المعادله
كود الداله كالتالى:
Dim Expr As String = value.Replace(" ", "")
Dim current_index As Integer = 0
Dim retval As Decimal = CalcTerm(Expr, current_index)
While current_index < Expr.Length
Select Case Expr.Chars(current_index)
Case "+"c
current_index += 1
retval += CalcTerm(Expr, current_index)
Case "-"c
current_index += 1
retval -= CalcTerm(Expr, current_index)
Case Else
Return String.Empty
End Select
End While
Return retval.ToString
End Function
Private Shared Function CalcExpression(ByVal value As String) As String
فى البدايه نقوم بحذف المسافات من المعادله و ذلك عن طريق عمل تبديل المسافه بقيمه فارغه
بعد ذلك نقوم بتعريف المتغير current_index و اعطيناه القيمه صفر، هذا المتغير سنعرف من خلاله الموقع الذى نحن فيه داخل المعادله.
بعد ذلك قمنا بتعريف المتغير retval و الذى يقوم بحساب قيمة الـ Term الأول داخل المعادله و ذلك لأن اى معادله ايا كانت تحتوى على الأقل Term واحد فقط لذا نقوم بحساب قيمته اولا و بعد ذلك نبدأ فى البحث عن علامة الجمع و الطرح.
لحساب اول Term قمنا يتمرير المعادله للداله CalcTerm و هى تطلب معاملين اولهما المعادله التى سنبدأ فى حساب الـ Term الموجود بها و الثانى هو الـ Index الذى من خلاله سنبدأ فى حساب قيمة الـ Term، بالنسبه للمعامل الثانى فيتم تمريره ByRef و ذلك لإنه يقوم بتحديث المتغير الذى يتم تمريره للمكان الذى تم التوقف عنده.
بعد حساب قيمة الـ Term الأول نقوم فى الدخول بحلقة While وشرط استمرارها هو ان يكون الـ current_index اقل من حجم المعادله و طالما ان هذا الشرط true سيتم الدخول على select case للحرف الذى مكانه هو current_index، فإن كان الحرف هو علامة الجمع فيتم زيادة current_index بواحد ثم استدعاء CalcTerm و تمرير المعادله له و المتغير current_index و القيمه المعاده يتم جمعها على القيمه الموجوده بـ retval و تخزين القيمه النهائيه بـ retval.
اما اذا كان الحرف هو علامة الطرح سيتم تنفيذ ما قد حدث مع علامة الجمع بإستثناء انه فى هذه الحاله سنطرح يدلا من ان نجمع.
اما اذا كان هذا الحرف ليس بعلامة جمع او طرح سنقوم بالرجوع من الداله بقيمه فارغه (و التى اعلم منها انه توجد مشكله).
فى حال الخروج من حلقة While يتم الرجوع بالقيمه الموجوده بـ retval على شكل نص.
نأتى الان للداله CalcTerm و التى تقوم بحساب قيمة Term معين و شكلها كالتالى:
Dim retval As Decimal = CalcNumber(value, index)
If index >= value.Length Then Return retval
While value.Chars(index) = "*"c OrElse value.Chars(index) = "/"c
Select Case value.Chars(index)
Case "*"c
index += 1
retval *= CalcNumber(value, index)
If index >= value.Length Then Exit While
Case "/"c
Try
index += 1
retval /= CalcNumber(value, index)
If index >= value.Length Then Exit While
Catch ex As DivideByZeroException
Throw ex
End Try
End Select
End While
Return retval
End Function
Private Shared Function CalcTerm(ByRef value As String, ByRef index As Integer) As Decimal
تقوم هذه الداله بحساب قيمة Term معين و ذلك بدءأ من Index معين يتم تمريره لها.
فى البدايه يتم تعريف متغير retval و الذى سيتم تخزين القيمه المعاده من هذا الـ term به.
تلاحظ انه بعد تعريف المتغير retval تم استدعاء الداله CalcNumber لتعود بالقيمه داخله و الهدف من هذه العمليه انه اى term يحتوى على رقم واحد فقط على الأقل لذا تم استدعاء هذه الداله كى تحول الحروف بدءا من الـ index لرقم (لا تشغل بالك الأن بكيفية قيامها بهذه العمليه فستعرف بعد قليل).
تقوم الداله CalcNumber بتحديث قيمة الـ Index الذى يمرر لها بالمكان الحالى داخل المعادله لذا تلاحظ ان اول سطر بعد تعريف المتغير retval هو التحقق من قيمة الـ index فإن كان اكبر من او يساوى عدد الحروف الخاصه بالمعادله فيتم الرجوع بقيمة المتغير retval.
غير ذلك يتم الدخول على جملة while حيث شرط تنفيذها هو ان يكون الحرف الحالى هو علامة الضرب او علامة القسمه.
اذا تم الدخول فى الحلقه يتم التحقق من هذا الحرف فغن كان علامة الضرب يتم زيادة الـ index بواحد ثم استدعاء الداله CalcNumber و تمرير لها الـ index الحالى و القيمه المعاده يتم ضربها فى قيمة المتغير retval و تخزين القيمه النهائيه بـ retval، بعد ذلك يتم التحقق من قيمة index فإن تخطت حجم المعادله او تساوت معها يتم الرجوع بـ retval.
اما إذا كان الحرف هو القسمه يتم عمل ما تم عمله مع عملية الضرب بإستثناء اننا هنا نقسم و لا نضرب.
الكود الخاص بالقسمه تم وضعه داخل try حتى اذا كانت القيمه التى سنقسم عليها صفر يتم رمى استثاء (و الذى من خلاله اعرف ان هناك خطأ فأتوقف و اظهر syntax error :blush: ).
بعد الخروج من الحلقه اقوم بالرجوع بقيمة retval.
نأتى الأن لأخر داله و هى CalcNumber تقوم هذه الداله بأخذ معاملين اولهم المعادله التى تحتوى على رقم بشكل نصى و تريد تحويله لرقم و المعامل الثانى هو رقم الت index و هو المكان الذى سنبدأ بقرأة الرقم منه. الداله تأخذ الشكل التالى:
Dim retval As Decimal = 0
While Char.IsDigit(value.Chars(index))
retval = 10 * retval + Val(value.Chars(index))
index += 1
If index = value.Length Then Return retval
End While
If value.Chars(index) <> "." Then Return retval
index += 1
Dim fract As Decimal = 1
While Char.IsDigit(value.Chars(index))
fract *= 0.1D
retval = retval + Val(value.Chars(index)) * fract
index += 1
If index = value.Length Then Return retval
End While
Return retval
End Function
Private Shared Function CalcNumber(ByRef value As String, ByRef index As Integer) As Decimal
تيبدا الداله (مثل الباقيين) بتعريف المتغير retval و الذى سيتم تخزين قيمه الرقم به، بعد ذلك يتم الدخول على حلقة while و شرطها هو ان الحرف الذى مكانه هو index هو Digit اى رقم.
يتم ضرب القيمه الموجوده فى retval بعشره ثم جمع الناتج بالحرف بعد تحويله لرقم و الناتج النهائى يتم تخزينه بـ retval، بعد ذلك يتم زيادة index بواحد، بعدها يتم التحقق من الـ index فإن كان يساوى او يتخطى عدد حروف المعادله يتم الرجوع بـ retval.
بعد الخروج من حلقة while يتم التحقق من الحرف الحالى فإن كان هذا الحرف غير النقطه فيتم الرجوع بقيمة retval و غير ذلك فهذا يعنى ان الرقم له بقيه و البقيه هى جزء عشرى لذا يتم الدخول على حلقة while جديده و هى مماثله تماما للأولى و لكن هنا بدلا من الضرب فى 10 يتم الضرب فى 0.1.
بعد الخروج من while يتم الرجوع بـ retval.
===============================================================================
دعنا نرتاح قليل ثم نكمل . . . . . . . . . . . . . . . . . . . . . ارتحنا خلاص نكمل بقى
لو تسئلونى نفسك فى ايه دلوقتى اقول لكم نفسى اشوف ghost :thumbup:
===============================================================================
انتهينا من الجزء الأول من الـ parser و الخاص بتحليل العلامات الحسابيه البسيطه.
نأتى الان لموضوع اضافة الأقواس.
صراحة موضوع الأقواس يجعلك مشوش حيث انه يلغى كل الاولويات فبإستخدامهم يمكنك تقديم الجمع على الضرب و الطرح على القسمه.
المشكله الثانيه هنا اننا قمنا بالفعل بكتابة الكود الخاص بالعمليات الحسابيه و ليس من العقل او المنطق ان نقوم بكتابة كود اخر يستخدم فى حالة الأقواس لذا لابد من ان نصنع طريقة للتعامل مع الأقواس و ايضا تكون مبنيه فوق ما سبق.
قبل ان تتطرق للوسيله التى اتبعها اريد ان اريك شيئا، انظر معى لهذه المعادله :
(3+4) * 5 - ( (2/3) + 7)
المعادله السابقه يمكن تقسيمها إلى عدة اقسام و بإستخدام اماكن لتخزين بعض القيم يمكن ان تصبح المعادله بالشكل كالتالى:
B = 2 / 3
A = A * 5
B = B + 7
A - B
A = 3 + 4
هل ترى ما أرى ان الأقواس كل ما تفعله هو صنع Expressions و ناتج هذه الـ Expressions يتم دمجه مع Expressions اخرى و هكذا.
كلام جميل و لكن المشكله هى اى Expression سنبدأ به او بمعنى اصح اى الأقواس سنبدأ فى تحليله اولا حيث انه قد يحتوى على اقواس اخرى ؟؟
و جوابى عليك هو انه اذا فكرت قليلا ستجد انه هناك دائما قوس لا يحتوى على قوس اخر فمثلا التعبير 2/3 موجود داخل قوس هذا القوس لا يحتوى على اى شئ إلا بعض العمليات البسيطه و التى يمكن تحليلها بإستخدام الداله CalcExpression.
يمكننا ان نعرف مكان اخر قوس مفتوح ثم نحضر القوس المغلق لهذا القوس المفتوح، لذا ما بينهم هو عباره عن Expression لذا نستدعى الداله CalcExpression لمحتوى هذا القوس و عندما تعود نقوم بإستبدال هذا القوس بمحتوياته بقيمته و هكذا دواليك حتى تنتهى الأقواس.
ايضا توجد مشكله اخرى انظر معى هذا المثال.
3 * ( 5 + 4 ) - ( 2 / 2 )
إذا قمنا بتطبيق ما قمنا بقوله فى الاعلى فسيكون ناتج هذه المعادله كالتالى:
3 * ( 5 + 4 ) - 1
3 * 9 - 1
3 * ( 5 + 4 ) - ( 2 / 2 )
كما ترى ناتج هذه العمليه هو 3 * 9 - 1 و السبب فى ذلك ان عمليه تحليل الأقواس ستظل تتم حتى تنتهى الأقواس و نسينا ان المعادله نفسها قد لا تحتوى على اقواس تتضمنها جميعا لذا الحل الوحيد لهذه المشكله هو اما ان نطلب من مستخدم الأله انه دائما لابد منه ان يكتب اقواس البدايه و النهايه و اما قبل ان نبدأ فى تحليل الأقواس ان نضيف قوسين البدايه و النهايه، بالطبع هذا هو الحل الأفضل لذا المعادله السابقه سيتم حلها كالتالى:
( 3 * ( 5 + 4 ) - ( 2 / 2 ) )
( 3 * ( 5 + 4 ) - 1 )
( 3 * 9 - 1 )
( 26 )
26
3 * ( 5 + 4 ) - ( 2 / 2 )
كما تلاحظ انه تم حل المعادله و الناتج هو الذى نريده بالظبط، السؤال الأن كيف سنقوم بتضمين تلك العمليه برمجيا.
الحل يكمن لدينا فى الدالتين IndexOf و LastIndexOf الموجودين بالنوع String.
كل ما سنقوم به هو اننا سندخل حلقة While و شرط تنفيذها هو ان مكان اول قوس مفتوح لا يساوى -1 لإنه عندما يساوى -1 فإنه لا يوجد قوس مفتوح داخل المعادله و بالتالى فإنه لا يوجد قوس مغلق و الحاله الوحيده التى تصبح فيها المعادله بدون اقواس هو عندما يكون لدينا الناتج النهائى.
داخل البرنامج توجد الداله Eval و التى تقوم بتحليل الأقواس و العوده بالقيمه النهائيه، و شكل الداله هو التالى: (لقد قمت بحذف بعض الأكواد منها لإنهم ينتموا لأجزاء اخرى من البرنامج)
value = "(" + value.Replace(" ", "").ToLower + ")"
While value.IndexOf("(") <> -1
Dim FirstBracket As Integer = value.LastIndexOf("("c)
Dim LastBracket As Integer = value.IndexOf(")"c, FirstBracket)
Dim res As String = value.Substring(FirstBracket, LastBracket - FirstBracket + 1)
value = value.Replace(res, CalcExpression(res.Substring(1, res.Length - 2)))
End While
Return value
End Function
Public Shared Function Eval(ByVal value As String) As String
الداله Eval تقوم بتمرير لها معادله معينه و هى تقوم بإرجاع لك ناتج المعادله.
اول سطر داخل الداله هو تحويلى للداله لحروف صغير و اضافة ")" فى بدايتها و "(" فى نهايتها بعد ذلك اقوم بالدخول على حلقو While و شرطها هو وجود القوس ")" داخل المعادله و تمثل بـ
value.IndexOf("(") <> -1داخل الحلقه اقوم بعمل متغير اسمه FirstBracket و هو يحتوى على اول قوس من الداخل انظر هذه الصوره
و كما ترى فى الصوره سبب اختيار هذا القوس انه لا يحتوى على اى واحد اخر بالتالى بإستبداله بقيمته سيساعد على جعل المعادله ابسط فى التحليل.
المتغير FirstBracket يحتوى على الـ Index الخاص بهذا القوس المفتوح و يتم معرفة مكانه بإستخدام الداله LastIndexOf و حيث ان لكل قوس مفتوح قوس خاص به يغلقه فسنقوم بإحضار القوس المغلق لهذا القوس بإستخدام الداله IndexOf و تمرير لها موقع القوس الحالىو حفظ الناتج داخل المتغير LastBracket.
قد يقول البعض منكم لماذا تم تمرير موقع القوس المفتوح للداله IndexOf لماذا لم نستدعيها بدون ارسال اى معاملات؟
انظر الصوره التاليه و بعدها اقرأ الشرح:
الفرق بين الدالتين IndexOf و LastIndexOf هو ان الاولى تحضر اول مكان يقابلها للقيمه المدخله و البحث يبدأ من اليسار اما الاخرى فهى مثلها تماما بإستثناء ان البحث يبدأ من اليمين.
فى حالتنا هذه اذا قمت بإستخدام الداله IndexOf بدون ارسال معاملات فستعود لك بالرقم الخاطى فكما ترى بالصوره السابقه القوس ذات اللون الأخضر (رقم 3) هو الذى تم العوده بقيمته و ليس القوس الاحمر (رقم 2) هو الذى تم العوده برقمه و لكن عندما تمرر رقم للداله IndexOf يتقوم ببدء البحث بدءا من هذا الرقم و عندما قمنا بتمرير الرقم الموجود بـ FirstBracket للداله IndexOf قامت بالرجوع بالرقم الصحيح (رقم القوس 2).
بعد ذلك قمت بإستخدام الداله Substring للحصول على القوس المفتوح و المغلق و ما بينهما ثم حفظتهما داخل المتغير res (اختصار لـ result).
بعد ذلك قمت بكتابة الكود التالى:
value = value.Replace(res, CalcExpression(res.Substring(1, res.Length - 2)))
هذه الصيغه مجمعه و قد تبدو معقده قليلا لذا سأقوم بتفكيكها لك حتى يسهل شرحها
B = CalcExpression( A )
C = Value.Replace( res , B )
Value = C
A = res.Substring( 1, res.Length - 2 )
فى البدايه قمنا بإستخلاص القيمه الموجوده مابين القوس المفتوح و المغلق وضعناها داخل A بعدها قمنا بإستدعاء الداله CalcExpression لما هو موجود بـ A و النتيجه تم تسجيلها بـ B بعد ذلك قمنا بعمل تبديل لقوسين و ما بينهما بما هو موجود بـ B (النتيجه لمحتوى ما بين القوسين) بعد ذلك جعلنا قيمة Value هى الموجوده بـ C.
ستستمر الحلقه بالعمل حتى تنتهى الأقواس بعدها سيتم العوده بمحتوى value.
و حتى هنا هذا هو اجابة السؤال الخاص بالأخ GHOST
التالى هو اضافات من عندى:
الـ Parser يعمل الان بشكل جيد جدا مع الارقام الصحيحه و الكسريه و الأقواس و لكن ماذا عن الأرقام السالبه ماذا لو كتبنا 3 * -5 النتيجه المتوقعه هى -15 و لكن ليس كل ما يتمناه المرء يدركه فالداله CalcNumber لاتفهم مامعنى هذا الكلام (الإشاره السالبه و الموجبه) لذا لابد منا ان نفهمها هذا الكلام.
ملحوظه لمن حمل نسخ سابقه من الأله : كنت قد كتب الداله CalcNumber اكثر من مره و لكن اخر مره قمت بكتابتها نسيت اضافة كود الأرقام السالبه لذا النسخه الموجوده فى هذا الدرس تحتوى على هذه الخاصيه.
الداله CalcNumber بعد التعديل تاخذ الشكل التالى:
Dim retval As Decimal = 0
Dim sign As Integer = 1
If value.Chars(index) = "+" Then
index += 1
ElseIf value.Chars(index) = "-" Then
sign = -1
index += 1
End If
While Char.IsDigit(value.Chars(index))
retval = 10 * retval + Val(value.Chars(index))
index += 1
If index = value.Length Then Return retval * sign
End While
If value.Chars(index) <> "." Then Return retval * sign
index += 1
Dim fract As Decimal = 1
While Char.IsDigit(value.Chars(index))
fract *= 0.1D
retval = retval + Val(value.Chars(index)) * fract
index += 1
If index = value.Length Then Return retval * sign
End While
Return retval * sign
End Function
Private Shared Function CalcNumber(ByRef value As String, ByRef index As Integer) As Decimal
الداله كما هى لم تتغير و لكنى قمت بإضافة بعض الأكود و هى :
If value.Chars(index) = "+" Then
index += 1
ElseIf value.Chars(index) = "-" Then
sign = -1
index += 1
End If
Dim sign As Integer = 1
قمت بتعريف المتغير sign و الذى سيحتوى على الأشاره بعد ذلك تحققت من الحرف الموجود بالـ index الحالى فإن كان "+" (لا تستغرب يوجد بعض الناس من يحب كتابة الأرقام الموجبه مسبوقه بـ +) قم بزيادة الـ Index بواحد فقط و إن كانت "-" قم بجعل sign يساوى -1 ثم زد Index بواحد.
ايضا قمت بجوار كلمة return داخل الداله بضرب retval بـ sign.
النسخه التنفيذيه
Calculator.rar
الكود
Calculator_Code.rar
باقى الشرح سأقوم بإضافته اليوم بإذن الله و هو عن تحليل الدوال داخل المعادله و التعامل مع انظمة الاعداد المختلفه.
و الله ولى التوفيق
