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

مشكلة في مكتبة math.h

بدأه Mohamed Amine Tag في 25 مارس 2010 · 7 رد · 1,686 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

هذه أول مشاركة لي بهذا المنتدى الرائع

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

المشكلة بسيطة وهي لماذا لا تعمل الدالة pow() من أجل الأعداد السالبة.

ولتوضيح أكثر، لنعتبر المثال التالي:

نحن نعلم أن الجذر التكعيبي لـ -8 هو -2 وعندما نجرب على الدالة بـ pow(-8,1/3) فإنه ينتج لي NaN .

مثال آخر: نحن نعلم أن -32 أس 1/5 يساوي -2 لكن عندما نستخدم الدالة pow(-32,1/5) فإن الإجابة هي NaN أي أنه لا يمكن حساب -32 أس 0.2 .

والكود هو:

#include <iostream>
#include <math.h>
int main()
{
    double x, y;
std::cout<<"Enter first number:\n";
std::cin>>x;
std::cout<<"Enter second number:\n";
std::cin>>y;
std::cout<<"Thereford ("<<x<<")^("<<y<<") = "<<pow(x,y)<<std::endl;
char rep;
std::cin>>rep;
return 0;
}

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

ومنهم من إستدل أن الجذر التكعيبي لـ -8 هو عدد مركب !!

أرجو أن أجد من يدلني، هل الدالة pow مخطئة في هذا التقدير أو محقة.

#2

تستطيع كتابه الكود بهذه الطريقه:

#include <iostream>
#include <math.h>

using namespace std;
double x;
double y;

int main()
{




std::cout<<"Enter first number:\n";
std::cin>>x;
std::cout<<"Enter second number:\n";
std::cin>>y;
std::cout<<"Thereford ("<<x<<")^("<<y<<") = "<< ((x<0)? -1*pow(-1*x,y):pow(x,y))  <<std::endl;

return 0;
}
1
tvquran_6.gif

#3

إبداع يا استاذ فهد ... فكرة ممتازة .. كنت محتار كيف احلها .

تسلم استاذنا .

تحياتي

1

OMANI FOR EVER

-------------------------------------------------

post-12787-12780191801974.jpg

-------------------------------------------------

#4
فهدالشلوي كتب:

تستطيع كتابه الكود بهذه الطريقه:

#include <iostream>
#include <math.h>

using namespace std;
double x;
double y;

int main()
{




std::cout<<"Enter first number:\n";
std::cin>>x;
std::cout<<"Enter second number:\n";
std::cin>>y;
std::cout<<"Thereford ("<<x<<")^("<<y<<") = "<< ((x<0)? -1*pow(-1*x,y):pow(x,y))  <<std::endl;

return 0;
}

جميل هذا الإختصار، لكني أريد حل دائم.

لأنه الجذر التربيعي لـ -8 على سبيل المثال لا يوجد.

لأنه عندما نطبق على الكود --10 أس 0.5 فإنه يعطيني إجابة -2... لكن لا يوجد جذر تربيعي لعدد سالب،

يوجد فقط للجذر التكعيبي أو أس 1 عل عدد فردي.

#5

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

لا أعتقد أن الموضوع متعلق بـ C أو ++C بالتحديد.

فمثلاً هنا نفس الموضوع مع Python, لذلك أعتقد أن الموضوع يتعلق بكتاب مكتبات الرياضيات, و كيف يقومون بحساب الجذر النوني للعدد السالب.

تحياتي...

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 25 مارس 2010 في 20:04

#6

تستطيع كتابة دالة خاصة بالجذر هكذا:

double root(double x,int y)
{

return (y%2==0)?pow(x,1.0/y):((x<0)?-1*pow(-1*x,1.0/y):pow(x,1.0/y));
}
tvquran_6.gif

#7

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

نعم المشكلة في مكتبة الرياضيات لأنهم أغفلو حساب أس عدد سالب.

لكن google يقوم بحسابها جيدا مثال (-32)^1/5

http://www.google.com/search?q=(-32)^(1/5)

أضن أنهم لم يعتمدو كثيرا على أساسيات الرياضيات، وهذه كارثة لأن هناك برامج للرسم تعتمد على مكتبة الرياضيات، حيث وجدت برنامج يقوم برسم الجهة الموجبة فقط للدالة x^1/5 .

وهذه المشكلة موجودة في المحرك الشهير wolframalpha http://www.wolframalpha.com/input/?i=plot+x^%281%2F3%29

أما الكود الخاص بالجذر التربيعي root فهو فعلا رائع بهذا الإختصار الجميل.

لقد وجدت حل مؤقت لهذه المشكلة وهو التالي:

#include <iostream>
#include <math.h>
bool equal(double x, double y){double eps=1e-5;     return fabs(x-y)<=eps;}
int main()
{
double x, y;
std::cout<<"Enter first number:\n";
std::cin>>x;
std::cout<<"Enter second number:\n";
std::cin>>y;
std::cout<<"Thereford ("<<x<<")^("<<y<<") = "<< ((equal(ceil((1-y)/(2*y)),(1-y)/(2*y)))? -1*pow(-1*x,y):pow(x,y))  <<std::endl;
return 0;
}

لقد إستعملتإختصارات الأخ فهد الشولي، فأنا لأول مرة أرى مثل هذه الاختصارات.

شكراٌ لكم

تم تعديل هذه المشاركة بواسطة Mohamed Amine Tag في 26 مارس 2010 في 01:44

#8

كما قيل لك من قبل السبب فى ان الداله pow تفشل فى احضار ناتج mimetex.cgi?(-8)^{0.33333} هو ان الناتج هو عدد مركب هذا اذا تم اعتبار الأشاره السالبه خاصه بالرقم 8 فقط و ليس بالناتج النهائى للعمليه اى mimetex.cgi?-(8^{0.33333})

اذا كانت دالة pow لا تقوم بما تريد يمكنك كتابة واحدة خاصه بك (و لكن احتمال كبير جدا ان تعطيك نفس النتيجه)، الخطوات كالتالى:

* الأس سنسميه exp و القيمه سنسميها base

  • قم بحساب log10 لـ base
  • قم بضرب الناتج من الخطوه 1 مع exp
  • قم بحساب alog10 للرقم الناتج من الخطوه 2
  • ناتج الخطوه 3 هو الرقم base مرفوعا للأس exp (سواء كان كسر او عدد صحيح).

ملاحظه:

  • إذا كان الـ Algorithm لأى رقم هو عدد مرات تكرار مضاعفات الـ base لهذا الـ algorithm داخل رقم معين فإن الـ Antilogrithm هو الـ base مرفوعا للرقم المدخل
    فمثلا mimetex.cgi?log10(12) = 1.079181246 فإن mimetex.cgi?alog10(1.079181246) = 10 ^ {
  • الخطوات السابقه تعطيك الـ pow لأى عدد مع اى اس تريد، إذا كنت تريد الحصول على الجذر لأى عدد مع اى جذر فقط قم بإبدال عملية الضرب الموجوده بالخطوه 2 بالقسمه.

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

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 26 مارس 2010 في 10:37 — السبب: تعديل خطأ كتابى

1

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

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