matherr(3)

الاسم
matherr - معالجة استثناءات مكتبة الرياضيات SVID

المكتبة
مكتبة الرياضيات (libm، -lm)

موجز
#include <math.h>

[[deprecated]] int matherr(struct exception *exc);

[[deprecated]] extern _LIB_VERSION_TYPE _LIB_VERSION;

الوصف
ملاحظة: الآلية الموصوفة في هذه الصفحة لم تعد مدعومة من glibc. قبل glibc 2.27، كانت قد وُسمت بأنها مهملة. منذ glibc 2.27، أُزيلت الآلية بالكامل. يجب على التطبيقات الجديدة استخدام التقنيات الموصوفة في math_error(7) و fenv(3). توثق هذه الصفحة آلية matherr() كمساعدة لصيانة ونقل التطبيقات القديمة.

يحدد تعريف واجهة النظام V (SVID) أن دوال الرياضيات المختلفة يجب أن تستدعي دالة تُسمى matherr() إذا اكتُشف استثناء رياضي. تُستدعى هذه الدالة قبل أن تعود دالة الرياضيات؛ بعد أن تعود matherr()، يعود النظام بعد ذلك إلى دالة الرياضيات، والتي بدورها تعود إلى المستدعي.

لاستخدام matherr()، يجب على المبرمج تعريف ماكرو اختبار الميزة _SVID_SOURCE (قبل تضمين أي ملفات رأس)، وتعيين القيمة _SVID_ إلى المتغير الخارجي _LIB_VERSION.

يوفر النظام نسخة مبدئية من matherr(). لا تفعل هذه النسخة شيئًا، وتعيد صفرًا (انظر أدناه لأهمية ذلك). يمكن تجاوز matherr() المبدئية بواسطة نسخة يُعرفها المبرمج، والتي ستُستدعى عند حدوث استثناء. تُستدعى الدالة بوسيط واحد، مؤشر إلى بنية exception، مُعرفة كالتالي:

    struct exception {
        int    type;      /* نوع الاستثناء */
        char  *name;      /* اسم الدالة المسببة للاستثناء */
        double arg1;      /* المعامل الأول للدالة */
        double arg2;      /* المعامل الثاني للدالة */
        double retval;    /* القيمة المعادة من الدالة */
    }

حقل type له إحدى القيم التالية:

DOMAIN
    حدث خطأ نطاق (كان وسيط الدالة خارج النطاق الذي عُرفت له الدالة). تعتمد قيمة الإرجاع على الدالة؛ يُضبط errno إلى EDOM.

SING
    حدث خطأ قطب (نتيجة الدالة هي لانهاية). قيمة الإرجاع في معظم الحالات هي HUGE (أكبر رقم فاصلة عائمة بدقة مفردة)، موقعة بشكل مناسب. في معظم الحالات، يُضبط errno إلى EDOM.

OVERFLOW
    حدث فيضان. في معظم الحالات، تُعاد القيمة HUGE، ويُضبط errno إلى ERANGE.

UNDERFLOW
    حدث تدفق سفلي. تُعاد 0.0، ويُضبط errno إلى ERANGE.

TLOSS
    فقدان كلي للدلالة. تُعاد 0.0، ويُضبط errno إلى ERANGE.

PLOSS
    فقدان جزئي للدلالة. هذه القيمة غير مستخدمة في glibc (وفي العديد من الأنظمة الأخرى).

الحقلان arg1 و arg2 هما المعاملان المقدمين للدالة (arg2 غير معرف للدوال التي تأخذ معاملاً واحداً فقط).

يحدد الحقل retval القيمة المُرجَعة التي سترجعها الدالة الرياضية إلى مستدعيها. يمكن للدالة matherr() المُعرَّفة من قبل المبرمج تعديل هذا الحقل لتغيير القيمة المُرجَعة للدالة الرياضية.

إذا أرجع الدالة matherr() صفراً، فإن النظام يضبط errno كما هو موصوف أعلاه، وقد يطبع رسالة خطأ على الخطأ المعياري (انظر أدناه).

إذا أرجع الدالة matherr() قيمة غير صفرية، فإن النظام لا يضبط errno، ولا يطبع رسالة خطأ.

  الدوال الرياضية التي تستخدم matherr()
يسرد الجدول أدناه الدوال والظروف التي تُستدعى فيها matherr(). يشير عمود "النوع" إلى القيمة المُسندة إلى exc->type عند استدعاء matherr(). عمود "النتيجة" هو القيمة المُرجَعة المبدئية المُسندة إلى exc->retval.

يصف العمودان "Msg?" و "errno" السلوك المبدئي إذا أرجع matherr() صفراً. إذا احتوى عمود "Msg?" على "y"، فإن النظام يطبع رسالة خطأ على الخطأ المعياري.

يستخدم الجدول الرموز والاختصارات التالية:

    x المعامل الأول للدالة
    y المعامل الثاني للدالة
    fin قيمة منتهية للمعامل
    neg قيمة سالبة للمعامل
    int قيمة صحيحة للمعامل
    o/f النتيجة فاضت
    u/f النتيجة نقصت
    |x| القيمة المطلقة لـ x
    X_TLOSS ثابت مُعرَّف في <math.h>
الدالة | Type | النتيجة | Msg? | errno
acos(|x|>1) | المجال | HUGE | y | EDOM
asin(|x|>1) | المجال | HUGE | y | EDOM
atan2(0,0) | المجال | HUGE | y | EDOM
acosh(x<1) | المجال | NAN | y | EDOM |
atanh(|x|>1) | المجال | NAN | y | EDOM |
atanh(|x|==1) | مفرد | (x>0.0)? | y | EDOM |
 |  | HUGE_VAL :
 |  | -HUGE_VAL
cosh(fin) o/f | OVERFLOW | HUGE | n | ERANGE
sinh(fin) o/f | OVERFLOW | (x>0.0) ? | n | ERANGE
 |  | HUGE : -HUGE
sqrt(x<0) | المجال | 0.0 | y | EDOM
hypot(fin,fin) o/f | OVERFLOW | HUGE | n | ERANGE
exp(fin) o/f | OVERFLOW | HUGE | n | ERANGE
exp(fin) u/f | UNDERFLOW | 0.0 | n | ERANGE
exp2(fin) o/f | OVERFLOW | HUGE | n | ERANGE
exp2(fin) u/f | UNDERFLOW | 0.0 | n | ERANGE
exp10(fin) o/f | OVERFLOW | HUGE | n | ERANGE
exp10(fin) u/f | UNDERFLOW | 0.0 | n | ERANGE
j0(|x|>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
j1(|x|>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
jn(|x|>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
y0(x>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
y1(x>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
yn(x>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
y0(0) | المجال | -HUGE | y | EDOM
y0(x<0) | المجال | -HUGE | y | EDOM
y1(0) | المجال | -HUGE | y | EDOM
y1(x<0) | المجال | -HUGE | y | EDOM
yn(n,0) | المجال | -HUGE | y | EDOM
yn(x<0) | المجال | -HUGE | y | EDOM
lgamma(fin) o/f | OVERFLOW | HUGE | n | ERANGE
lgamma(-int) or | مفرد | HUGE | y | EDOM
lgamma(0)
tgamma(fin) o/f | OVERFLOW | HUGE_VAL | n | ERANGE
tgamma(-int) | مفرد | NAN | y | EDOM
tgamma(0) | مفرد | copysign( | y | ERANGE
 |  | HUGE_VAL,x)
log(0) | مفرد | -HUGE | y | EDOM
log(x<0) | المجال | -HUGE | y | EDOM
log2(0) | مفرد | -HUGE | n | EDOM |
log2(x<0) | المجال | -HUGE | n | EDOM |
log10(0) | مفرد | -HUGE | y | EDOM
log10(x<0) | المجال | -HUGE | y | EDOM
pow(0.0,0.0) | المجال | 0.0 | y | EDOM
pow(x,y) o/f | OVERFLOW | HUGE | n | ERANGE
pow(x,y) u/f | UNDERFLOW | 0.0 | n | ERANGE
pow(NaN,0.0) | المجال | x | n | EDOM
0**neg | المجال | 0.0 | y | EDOM |
neg**non-int | المجال | 0.0 | y | EDOM
scalb() o/f | OVERFLOW | (x>0.0) ? | n | ERANGE
 |  | HUGE_VAL :
 |  | -HUGE_VAL
scalb() u/f | UNDERFLOW | copysign( | n | ERANGE
 |  | 0.0,x)
fmod(x,0) | المجال | x | y | EDOM
remainder(x,0) | المجال | NAN | y | EDOM |

السمات
للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر attributes(7).
الواجهة | السمة | القيمة
matherr() | سلامة الخيوط | MT-Safe

أمثلة
يُظهر البرنامج المثال استخدام matherr() عند استدعاء log(3). يأخذ البرنامج حتى ثلاث وسائط لسطر الأوامر. الوسيطة الأولى هي رقم الفاصلة العائمة الذي يُعطى لـ log(3). إذا وُفرت الوسيطة الثانية الاختيارية، فسيُضبط _LIB_VERSION على _SVID_ بحيث يُستدعى matherr()، ويُستخدم العدد الصحيح المقدم في وسيطة سطر الأوامر كقيمة إرجاع من matherr(). إذا وُفرت وسيطة سطر الأوامر الثالثة الاختيارية، فإنها تُحدد قيمة إرجاع بديلة يجب أن يُسندها matherr() كقيمة إرجاع لدالة الرياضيات.

التشغيل المثال التالي، حيث يُعطى log(3) وسيطة بقيمة 0.0، لا يستخدم matherr():

    $ ./a.out 0.0
    errno: Numerical result out of range
    x=-inf

في التشغيل التالي، يُستدعى matherr()، ويُرجع 0:

    $ ./a.out 0.0 0
    matherr SING exception in log() function
            args:   0.000000, 0.000000
            retval: -340282346638528859811704183484516925440.000000
    log: SING error
    errno: Numerical argument out of domain
    x=-340282346638528859811704183484516925440.000000

الرسالة "log: خطأ SING" طُبعت بواسطة مكتبة C.

في التشغيل التالي، يُستدعى matherr()، ويُرجع قيمة غير صفرية:

    $ ./a.out 0.0 1
    matherr SING exception in log() function
            args:   0.000000, 0.000000
            retval: -340282346638528859811704183484516925440.000000
    x=-340282346638528859811704183484516925440.000000

في هذه الحالة، لم تطبع مكتبة C رسالة، ولم يُضبط errno.

في التشغيل التالي، يُستدعى matherr()، ويُغير قيمة إرجاع دالة الرياضيات، ويُرجع قيمة غير صفرية:

    $ ./a.out 0.0 1 12345.0
    matherr SING exception in log() function
            args:   0.000000, 0.000000
            retval: -340282346638528859811704183484516925440.000000
    x=12345.000000

  مصدر البرنامج
    #define _SVID_SOURCE
    #include <errno.h>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>

    static int matherr_ret = 0;     /* Value that matherr()
                                       should return */
    static int change_retval = 0;   /* Should matherr() change
                                       function's return value? */
    static double new_retval;       /* New function return value */

    int
    matherr(struct exception *exc)
    {
        fprintf(stderr, "matherr %s exception in %s() function\n",
                (exc->type == DOMAIN) ?    "DOMAIN" :
                (exc->type == OVERFLOW) ?  "OVERFLOW" :
                (exc->type == UNDERFLOW) ? "UNDERFLOW" :
                (exc->type == SING) ?      "SING" :
                (exc->type == TLOSS) ?     "TLOSS" :
                (exc->type == PLOSS) ?     "PLOSS" : "???",
                exc->name);
        fprintf(stderr, "        args:   %f, %f\n",
                exc->arg1, exc->arg2);
        fprintf(stderr, "        retval: %f\n", exc->retval);

        if (change_retval)
            exc->retval = new_retval;

        return matherr_ret;
    }

    int
    main(int argc, char *argv[])
    {
        double x;

        if (argc < 2) {
            fprintf(stderr, "Usage: %s <argval>"
                    " [<matherr-ret> [<new-func-retval>]]\n", argv[0]);
            exit(EXIT_FAILURE);
        }

        if (argc > 2) {
            _LIB_VERSION = _SVID_;
            matherr_ret = atoi(argv[2]);
        }

        if (argc > 3) {
            change_retval = 1;
            new_retval = atof(argv[3]);
        }

        x = log(atof(argv[1]));
        if (errno != 0)
            perror("errno");

        printf("x=%f\n", x);
        exit(EXIT_SUCCESS);
    }

انظر أيضًا
fenv(3), math_error(7), standards(7)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.