1MATHERR(3)                 Linux Programmer's Manual                MATHERR(3)
2
3
4

NAME

6       matherr - SVID math library exception handling
7

SYNOPSIS

9       #define _SVID_SOURCE             /* See feature_test_macros(7) */
10       #include <math.h>
11
12       int matherr(struct exception *exc);
13
14       extern _LIB_VERSION_TYPE _LIB_VERSION;
15
16       Link with -lm.
17

DESCRIPTION

19       The  System  V  Interface Definition (SVID) specifies that various math
20       functions should invoke a function called matherr() if a math exception
21       is detected.  This function is called before the math function returns;
22       after matherr() returns, the system then returns to the math  function,
23       which in turn returns to the caller.
24
25       The matherr() mechanism is supported by glibc, but is now obsolete: new
26       applications should use the techniques described in  math_error(7)  and
27       fenv(3).   This  page documents the glibc matherr() mechanism as an aid
28       for maintaining and porting older applications.
29
30       To employ matherr(), the programmer must define the  _SVID_SOURCE  fea‐
31       ture  test  macro  (before  including any header files), and assign the
32       value _SVID_ to the external variable _LIB_VERSION.
33
34       The system provides a default version of matherr().  This version  does
35       nothing,  and  returns  zero  (see below for the significance of this).
36       The default matherr() can be overridden by  a  programmer-defined  ver‐
37       sion,  which will be invoked when an exception occurs.  The function is
38       invoked with one argument, a pointer to an exception structure, defined
39       as follows:
40
41           struct exception {
42               int    type;      /* Exception type */
43               char  *name;      /* Name of function causing exception */
44               double arg1;      /* 1st argument to function */
45               double arg2;      /* 2nd argument to function */
46               double retval;    /* Function return value */
47           }
48
49       The type field has one of the following values:
50
51       DOMAIN      A  domain error occurred (the function argument was outside
52                   the range for which the function is defined).   The  return
53                   value depends on the function; errno is set to EDOM.
54
55       SING        A pole error occurred (the function result is an infinity).
56                   The return value in most cases is HUGE (the largest  single
57                   precision floating-point number), appropriately signed.  In
58                   most cases, errno is set to EDOM.
59
60       OVERFLOW    An overflow occurred.  In most cases,  the  value  HUGE  is
61                   returned, and errno is set to ERANGE.
62
63       UNDERFLOW   An  underflow  occurred.  0.0 is returned, and errno is set
64                   to ERANGE.
65
66       TLOSS       Total loss of significance.  0.0 is returned, and errno  is
67                   set to ERANGE.
68
69       PLOSS       Partial  loss  of  significance.   This  value is unused on
70                   glibc (and many other systems).
71
72       The arg1 and arg2 fields are the arguments  supplied  to  the  function
73       (arg2 is undefined for functions that take only one argument).
74
75       The retval field specifies the return value that the math function will
76       return to its caller.  The programmer-defined matherr() can modify this
77       field to change the return value of the math function.
78
79       If  the  matherr() function returns zero, then the system sets errno as
80       described above, and may print an error message on standard error  (see
81       below).
82
83       If the matherr() function returns a nonzero value, then the system does
84       not set errno, and doesn't print an error message.
85
86   Math functions that employ matherr()
87       The table below lists the functions and circumstances  in  which  math‐
88       err()  is  called.   The  "Type" column indicates the value assigned to
89       exc->type when calling matherr().  The "Result" column is  the  default
90       return value assigned to exc->retval.
91
92       The  "Msg?"  and "errno" columns describe the default behavior if math‐
93       err() returns zero.  If the "Msg?" columns contains "y", then the  sys‐
94       tem prints an error message on standard error.
95
96       The table uses the following notations and abbreviations:
97
98              x        first argument to function
99              y        second argument to function
100              fin      finite value for argument
101              neg      negative value for argument
102              int      integral value for argument
103              o/f      result overflowed
104              u/f      result underflowed
105              |x|      absolute value of x
106              X_TLOSS  is a constant defined in <math.h>
107
108       Function             Type        Result         Msg?   errno
109       acos(|x|>1)          DOMAIN      HUGE            y     EDOM
110       asin(|x|>1)          DOMAIN      HUGE            y     EDOM
111       atan2(0,0)           DOMAIN      HUGE            y     EDOM
112       acosh(x<1)           DOMAIN      NAN             y     EDOM
113       atanh(|x|>1)         DOMAIN      NAN             y     EDOM
114       atanh(|x|==1)        SING        (x>0.0)?        y     EDOM
115                                        HUGE_VAL :
116                                        -HUGE_VAL
117       cosh(fin) o/f        OVERFLOW    HUGE            n     ERANGE
118       sinh(fin) o/f        OVERFLOW    (x>0.0) ?       n     ERANGE
119                                        HUGE : -HUGE
120       sqrt(x<0)            DOMAIN      0.0             y     EDOM
121       hypot(fin,fin) o/f   OVERFLOW    HUGE            n     ERANGE
122       exp(fin) o/f         OVERFLOW    HUGE            n     ERANGE
123       exp(fin) u/f         UNDERFLOW   0.0             n     ERANGE
124       exp2(fin) o/f        OVERFLOW    HUGE            n     ERANGE
125       exp2(fin) u/f        UNDERFLOW   0.0             n     ERANGE
126       exp10(fin) o/f       OVERFLOW    HUGE            n     ERANGE
127       exp10(fin) u/f       UNDERFLOW   0.0             n     ERANGE
128       j0(|x|>X_TLOSS)      TLOSS       0.0             y     ERANGE
129       j1(|x|>X_TLOSS)      TLOSS       0.0             y     ERANGE
130       jn(|x|>X_TLOSS)      TLOSS       0.0             y     ERANGE
131       y0(x>X_TLOSS)        TLOSS       0.0             y     ERANGE
132       y1(x>X_TLOSS)        TLOSS       0.0             y     ERANGE
133       yn(x>X_TLOSS)        TLOSS       0.0             y     ERANGE
134
135       y0(0)                DOMAIN      -HUGE           y     EDOM
136       y0(x<0)              DOMAIN      -HUGE           y     EDOM
137       y1(0)                DOMAIN      -HUGE           y     EDOM
138       y1(x<0)              DOMAIN      -HUGE           y     EDOM
139       yn(n,0)              DOMAIN      -HUGE           y     EDOM
140       yn(x<0)              DOMAIN      -HUGE           y     EDOM
141       lgamma(fin) o/f      OVERFLOW    HUGE            n     ERANGE
142       lgamma(-int) or      SING        HUGE            y     EDOM
143         lgamma(0)
144       tgamma(fin) o/f      OVERFLOW    HUGE_VAL        n     ERANGE
145       tgamma(-int)         SING        NAN             y     EDOM
146       tgamma(0)            SING        copysign(       y     ERANGE
147                                        HUGE_VAL,x)
148       log(0)               SING        -HUGE           y     EDOM
149       log(x<0)             DOMAIN      -HUGE           y     EDOM
150       log2(0)              SING        -HUGE           n     EDOM
151       log2(x<0)            DOMAIN      -HUGE           n     EDOM
152       log10(0)             SING        -HUGE           y     EDOM
153       log10(x<0)           DOMAIN      -HUGE           y     EDOM
154       pow(0.0,0.0)         DOMAIN      0.0             y     EDOM
155       pow(x,y) o/f         OVERFLOW    HUGE            n     ERANGE
156       pow(x,y) u/f         UNDERFLOW   0.0             n     ERANGE
157       pow(NaN,0.0)         DOMAIN      x               n     EDOM
158       0**neg               DOMAIN      0.0             y     EDOM
159       neg**non-int         DOMAIN      0.0             y     EDOM
160       scalb() o/f          OVERFLOW    (x>0.0) ?       n     ERANGE
161                                        HUGE_VAL :
162                                        -HUGE_VAL
163       scalb() u/f          UNDERFLOW   copysign(       n     ERANGE
164                                          0.0,x)
165       fmod(x,0)            DOMAIN      x               y     EDOM
166       remainder(x,0)       DOMAIN      NAN             y     EDOM
167

EXAMPLE

169       The  example  program  demonstrates  the  use of matherr() when calling
170       log(3).  The program takes up to  three  command-line  arguments.   The
171       first  argument is the floating-point number to be given to log(3).  If
172       the optional second argument is provided, then _LIB_VERSION is  set  to
173       _SVID_  so  that  matherr()  is called, and the integer supplied in the
174       command-line argument is used as the return value from  matherr().   If
175       the optional third command-line argument is supplied, then it specifies
176       an alternative return value that matherr() should assign as the  return
177       value of the math function.
178
179       The  following  example  run, where log(3) is given an argument of 0.0,
180       does not use matherr():
181
182           $ ./a.out 0.0
183           errno: Numerical result out of range
184           x=-inf
185
186       In the following run, matherr() is called, and returns 0:
187
188           $ ./a.out 0.0 0
189           matherr SING exception in log() function
190                   args:   0.000000, 0.000000
191                   retval: -340282346638528859811704183484516925440.000000
192           log: SING error
193           errno: Numerical argument out of domain
194           x=-340282346638528859811704183484516925440.000000
195
196       The message "log: SING error" was printed by the C library.
197
198       In the following run, matherr() is called, and returns a nonzero value:
199
200           $ ./a.out 0.0 1
201           matherr SING exception in log() function
202                   args:   0.000000, 0.000000
203                   retval: -340282346638528859811704183484516925440.000000
204           x=-340282346638528859811704183484516925440.000000
205
206       In this case, the C library did not print a message, and errno was  not
207       set.
208
209       In  the following run, matherr() is called, changes the return value of
210       the math function, and returns a nonzero value:
211
212           $ ./a.out 0.0 1 12345.0
213           matherr SING exception in log() function
214                   args:   0.000000, 0.000000
215                   retval: -340282346638528859811704183484516925440.000000
216           x=12345.000000
217
218   Program source
219
220       #define _SVID_SOURCE
221       #include <errno.h>
222       #include <math.h>
223       #include <stdio.h>
224       #include <stdlib.h>
225
226       static int matherr_ret = 0;     /* Value that matherr()
227                                          should return */
228       static int change_retval = 0;   /* Should matherr() change
229                                          function's return value? */
230       static double new_retval;       /* New function return value */
231
232       int
233       matherr(struct exception *exc)
234       {
235           fprintf(stderr, "matherr %s exception in %s() function\n",
236                  (exc->type == DOMAIN) ?    "DOMAIN" :
237                  (exc->type == OVERFLOW) ?  "OVERFLOW" :
238                  (exc->type == UNDERFLOW) ? "UNDERFLOW" :
239                  (exc->type == SING) ?      "SING" :
240                  (exc->type == TLOSS) ?     "TLOSS" :
241                  (exc->type == PLOSS) ?     "PLOSS" : "???",
242                   exc->name);
243           fprintf(stderr, "        args:   %f, %f\n",
244                   exc->arg1, exc->arg2);
245           fprintf(stderr, "        retval: %f\n", exc->retval);
246
247           if (change_retval)
248               exc->retval = new_retval;
249
250           return matherr_ret;
251       }
252
253       int
254       main(int argc, char *argv[])
255       {
256           double x;
257
258           if (argc < 2) {
259               fprintf(stderr, "Usage: %s <argval>"
260                       " [<matherr-ret> [<new-func-retval>]]\n", argv[0]);
261               exit(EXIT_FAILURE);
262           }
263
264           if (argc > 2) {
265               _LIB_VERSION = _SVID_;
266               matherr_ret = atoi(argv[2]);
267           }
268
269           if (argc > 3) {
270               change_retval = 1;
271               new_retval = atof(argv[3]);
272           }
273
274           x = log(atof(argv[1]));
275           if (errno != 0)
276               perror("errno");
277
278           printf("x=%f\n", x);
279           exit(EXIT_SUCCESS);
280       }
281

SEE ALSO

283       fenv(3), math_error(7), standards(7)
284

COLOPHON

286       This page is part of release 3.53 of the Linux  man-pages  project.   A
287       description  of  the project, and information about reporting bugs, can
288       be found at http://www.kernel.org/doc/man-pages/.
289
290
291
292Linux                             2010-09-10                        MATHERR(3)
Impressum