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

مساعده في سلسله تايلور

رائج
بدأه empror9 في 9 يوليو 2010 · 59 رد · 3,225 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#51

السلام عليكم

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

لا أوافقك الرأي :sleep: مع احتراي التام لك :wub:

الغموض لا يتعلق باستخدام الإستدعاء الذاتي بقدرما يتعلق بالطريقة المُعتمدة في حل الكود .. فيمكننا أن نجد غموضا في كود بدائي (يحتوي على 10 أسطر مثلا) و لكن المنهجية المُتبعة لحله (بالتأكيد) ستكون سيئة ...!

سأعود و أشرح الطريقة التي اتبعتها في حل التمرين.

الفكرة ببساطة هي محاولة اختزال الدالتين fact و pow في دالة واحدة.

float sin(float x,int r)
{
  int i=0,n=0;
  float result=0;
  if(r%2==0) r++;
  while(n!=r)
  {
    if(x==0) result=1;
     else
     {
       if(++i%2!=0)
         result+=(x*sin(x,n-1)/n*sin(1,n-1));
        else
         result+=(-x*sin(x,n-1)/n*sin(1,n-1));
      }
       n+=2*n+1;
   }
  return result;
}

الدالة sin تستقبل متغيرين أحدهما float و الآخر int

بالنسبة لـ x فهي الزاوية المُراد حساب جيبها و المتغير r عبارة عن الأس الذي نتوقف عنده.

الهدف من المتغير i هو تغيير إشارة الجزء المُضاف للمجموع في كل مرة فإذا كان i فرديا فإننا نضع إشارة موجبة أمام المجموع أما إذا كان i زوجيا فإننا نضع إشارة سالبة أمام المجموع.

أما المتغير n فهو يمثل الأس في كل مرة و السبب في كتابة هذا السطر:

n+=2*n+1;

لأن الأس فردي دائما , لاحظ أننا نتوقف عندما تكون n تساوي r أي أن المتغير n يمثل الأس المؤقت.

لاحظ أننا نزيد المتغير r بواحد عندما يكوت زوجيا و ذلك لكي لا تكون الدوارة غير منتهية.

انتظر تعليقك على الدالة .. أريد أن أضعها في كود و يعمل :)

اقتباس
less efficient as compared to the non-recursive counterparts as the overhead involved in entering,re-entering and exiting a block is avoided in case of the non recursive forms. its also possible to identify a number of local variables which need not be saved and restored with the help of stacks and this unwanted stacking activity is avoided in the non-recursive versions

يا ريت تترجم لي هذه الفقرة .. جربت مع جوجل بس ما نجحت :blush:

اقتباس
دعك من تلك الطريقة - سأعطيك واحدة جديدة تعطي نتائج ممتازة

أريد الطريقتان معا :lol:

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

بالنسبة للطريقة الثانية فهي جميلة جدا .. مع أني لم أفهمها بشكل كامل :blush:

جاري التفكير ... :blink:

#52

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

#include<iostream>
using namespace std;

int sum(int num1,int num2)
{ 
	return num1 + num2;
}

float Div(int num1,int num2)
{
	return (float)num1/num2;
}

int main()
{
	char q = 'y';

	int a,b,choice;

	do
	{
		cout<< "Welcome to the super program\n\n"

			<< "[1] finding the sum of the numbers.\n"
			<< "[2] finding the divide of the numbers.\n\n"

			<< "Please enter your choice : ";

		cin >> choice;

		while(choice != 1 && choice != 2)
		{
			cout << "\nPlease choice either '1' or '2' : ";
			cin >> choice;
		}

		cout << "\nPlease enter two numbers : ";
		cin >> a >> b;

		if(choice == 1)
			cout << a << '+' << b << '=' <<
			sum(a,b) << endl;
		else
			cout << a << '/' << b << '=' <<
			Div(a,b) << endl;

		cout << "Want to repeat ? ( y , n ) :";
		cin >> q;
	}
	while(q == 'y');

	return 0;
}

تم تعديل هذه المشاركة بواسطة namespace في 11 يوليو 2010 في 22:57

2

البرمجة = الرياضيات

#53

السلام عليكم

أرجو من كافة الأعضاء الكرام الإجابة على أسئلتي الموجودة في المشاركة رقم 50 و 51 و الله لا يضيع أجر من أحسن عملا ... :blush:

بانتظار الرد :resentful:

#54

اهلين شباب الان وضحت الصوره بالنسبه للبرنامج الذي نقوم باستخدام الدوال فيه

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

بس فيه سؤال ما اقدر استخدم نفس القيم الي هم num1,num2 على طول من غير ما اعرف a و b في الداله الرئيسيه؟

بالنسبه للكود الاول انتظرك نيم سبيس حتى اعرف اذا هو صحيح او لا

يسلمكم ربي ع المشاركه ويعطيكم العافيه

#55

السلام عليكم

اقتباس
ما اقدر استخدم نفس القيم الي هم num1,num2 على طول من غير ما اعرف a و b في الداله الرئيسيه؟

راجع ما ذكرتُه لك سابقا:

المتغيرين num1 و num2 تم الإعلان عنهما في الدالة السابقة أي أنهما متغيرات خاصة و لا يمكن رؤيتهم خارج الإطار الذي تم الإعلان عنهم فيه , لذلك يجب أن تعلن عن متغيرات جديدة بنفس الإسم أو باسم مخالف (الإختيار لك).

اقتباس
بالنسبه للكود الاول انتظرك نيم سبيس حتى اعرف اذا هو صحيح او لا

هل السؤال خاص بنيم سبيس !؟

يعني لا تريد الإجابة من غيره ...!؟

إذا كان الجواب "لا" فأرجو منك أن توضح أي كود تقصد .. حتى أساعدك.

أما إذا كان الجواب "نعم" فسأحذف هذا الجزء من المشاركة ...!

بانتظار الرد.

#56

اهلين اخ خالد

اهاا اوكي الان كويس

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

انا اقصد هذا الكود

float cos(float x)  
{  
        float result = 1;  

        int limit = 10;  
        int sign = -1;  

        for(int i=2 ; i<limit ; i+=2,sign=-sign)  
                result += sign*result*(x*x)/(i*(i-1));  

        return result;  
}

لاحظ ان هذا هو الكوساين وليس الساين الذي كتبه الاخ نيم سبيس

انا عدلت عليه وان شاء الله انه صح بس المشكله اني معقد كثير من ماده الرياضيات واحب كل خطوه امشي فيها تكون صحيحه ميه في الميه

طبعا هذا باستخدم القانون term الي موجود في الصفحه السابقه على ما اعتقد لانه يعطي نتائج ادق من القوانين الموجوده في اول مشاركه لي

وشاكر لكم جميعا

#57

السلام عليكم

الان اقتربت من الانتهاء من البرنامج الذي يقوم بحساب متسلسه تايلور

الان اريد التعدل على الداله cos(x) بحيث اذا ساوت صفر اريد ان اظهر رقم صفر وبالتالي فـ ان قيمه tan تساوي مالانهايه

انظر الداله

double cos(double x) 
{ 
		x=fmod(x,M_PI*2);
        double result = 1;
		double term = 1;
        int limit = 20;
        int sign = -1;

        for(int i=2 ; i<limit ; i+=2,sign=-sign) {
                term = -term*x*x/(i*(i-1)); //
                result += term;                 //make this change
        };
			if(result == 2.67949e-008)
						{
				            cout <<"cos(" << x <<") is: " << "0" <<endl;
						}
				        else if (result == 0)
						{
							cout <<"cos(" << x <<") is: " << "0" <<endl;
						}
						else
						{
							cout <<"cos(" << x <<") is: " << result <<endl;
						}
        return result; 
}

وحاولت ايضا باستخدامه عند استدعاء الداله

cout <<"Enter a value of 'x' in Radian, x => ";
					cin >> x;		
						result = sin(x);
							cout <<"sin(" << x <<") is: " << result <<endl;
						result = cos(x);
						if(result == 2.67949e-008)
						{
				            cout <<"cos(" << x <<") is: " << "0" <<endl;
						}
				        else if (result == 0)
						{
							cout <<"cos(" << x <<") is: " << "0" <<endl;
						}
						else
						{
							cout <<"cos(" << x <<") is: " << result <<endl;
						}

لكن للاسف لاجدوى من ذلك

عندي اخر سؤال ايضا

ماذا يعني الكود هذا x=fmod(x,M_PI*2);

ومايعني M_PI ؟

وشاكر لكم مقدما

#58
اقتباس
الغموض لا يتعلق باستخدام الإستدعاء الذاتي بقدرما يتعلق بالطريقة المُعتمدة في حل الكود

+1

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

اقتباس
لذلك فإنني أرجوا منك أن تعطينا طريقة بسيطة

اعلم انها جائت متأخر و لكنى اعتقدت انكم قرأتم كود الداله sin و cos هناك و لكن على ما يبدو انه لم يتم، انظروا للكود التالى:

// preprocessor constants
#define PI  3.14159265358979323846  // pi constant

// preprocessor macros
#define ToDegree(RAD) ((RAD * 180) / PI)
#define ToRadian(DEG) ((DEG * PI ) / 180)

double sin(double x)
{
        float angel[]={0,30,90,180,210,270,360}; // angle lookup table for readable number and
        float values[]={0,0.5,1,0,-0.5,-1,0};   // it's values in degree

        double deg=ToDegree(x);  // convert x to degree

        for (;;)
                if (deg>=360)     // if x greater than 360
                        deg-=360;  // decrease it by 360
                else                       // otherwise
                        break;   // break infinite loop

        for (int c=0; c<7; c++)           // search look up table for angle
                if (deg==angel[c])              // if exist
                        return values[c]; // return its value

        // now i'll calculate sin using formula
        // sin x = x - (x^3/3!) + (x^5/5!) - (x^7/7!) ....

        double numerator = x;
        double denominator = 1.0;
        double sign = 1.0;
        double value = 0;

        for ( int i = 1; i <= 10; i++ )
        {
                value += numerator / denominator * sign;
                numerator *= x * x;
                denominator *= i*2 * (i*2+1);
                sign *= -1;
        }

        return value;
}

double cos(double x)
{
        float angel[]={0,90,120,180,270,300,360};
        float values[]={1,0,-0.5,-1,0,0.5,1};

        double deg=ToDegree(x);

        for (;;)
                if (deg>=360)
                        deg-=360;
                else
                        break;

        for (int c=0; c<7; c++)
                if (deg==angel[c])
                        return values[c];

        double numerator = 1.0;
        double denominator = 1.0;
        double sign = 1.0;
        double cos = 0;

        for ( int i = 1; i <= 10; i++ )
        {
                cos += numerator / denominator * sign;
                sign *= -1;
                numerator *= x * x;
                denominator *= (i*2-1) * i*2;
        }

        return cos;
}

double tan(double x)
{ return sin(x)/cos(x); }

هذا هو تضمين الدوال sin و cos و tan الموجود بالرابط فى المشاركه الرابعه.

بالنسبه للسؤال الخاص بمشكلة الـ infinity الخاصه بأحد نتائج الداله sin، الكود التالى يحتوى على دالتين يتحققا من طبيعة الرقم العائد إذا ما كان Nan او Infinity

typedef unsigned int uint32;

static bool isNan(float f)
{
    uint32 i = *(uint32*)&f;
    return i == 0x7fffffff || //  sNan
           i == 0x7fc00000 || //  qNan
           i == 0xffffffff || // -sNan
           i == 0xffc00000;   // -qNan
}

static bool isInfinite(float f)
{
    uint32 i = *(uint32*)&f;
    return i == 0x7f800000 || // +Infinite
           i == 0xff800000;   // -Infinite
}

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

تم تعديل هذه المشاركة بواسطة محمد علاء الدين في 26 يوليو 2010 في 22:51

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

#59

ماذا عن السؤال الذي طرحته في المشاركه رقم 57

#60

السلام عليكم

أين الخطأ في هذه الدالة:

float sin(float x,int r)
{
  int i=0,n=0;
  float result=0;
  if(r%2==0) r++;
  while(n!=r)
  {
    if(x==0) result=1;
     else
     {
       if(++i%2!=0)
         result+=(x*sin(x,n-1)/n*sin(1,n-1));
        else
         result+=(-x*sin(x,n-1)/n*sin(1,n-1));
      }
       n+=2*n+1;
   }
  return result;
}

تحياتي.

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

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…