]>
Commit | Line | Data |
---|---|---|
5f1f495c MK |
1 | '\" t |
2 | .\" Copyright (c) 2008, Linux Foundation, written by Michael Kerrisk | |
3 | .\" <mtk.manpages@gmail.com> | |
4 | .\" | |
93015253 | 5 | .\" %%%LICENSE_START(VERBATIM) |
5f1f495c MK |
6 | .\" Permission is granted to make and distribute verbatim copies of this |
7 | .\" manual provided the copyright notice and this permission notice are | |
8 | .\" preserved on all copies. | |
9 | .\" | |
10 | .\" Permission is granted to copy and distribute modified versions of this | |
11 | .\" manual under the conditions for verbatim copying, provided that the | |
12 | .\" entire resulting derived work is distributed under the terms of a | |
13 | .\" permission notice identical to this one. | |
14 | .\" | |
15 | .\" Since the Linux kernel and libraries are constantly changing, this | |
16 | .\" manual page may be incorrect or out-of-date. The author(s) assume no | |
17 | .\" responsibility for errors or omissions, or for damages resulting from | |
18 | .\" the use of the information contained herein. The author(s) may not | |
19 | .\" have taken the same level of care in the production of this manual, | |
20 | .\" which is licensed free of charge, as they might when working | |
21 | .\" professionally. | |
22 | .\" | |
23 | .\" Formatted or processed versions of this manual, if unaccompanied by | |
24 | .\" the source, must acknowledge the copyright and authors of this work. | |
4b72fb64 | 25 | .\" %%%LICENSE_END |
5f1f495c | 26 | .\" |
9ba01802 | 27 | .TH MATHERR 3 2019-03-06 "Linux" "Linux Programmer's Manual" |
5f1f495c MK |
28 | .SH NAME |
29 | matherr \- SVID math library exception handling | |
30 | .SH SYNOPSIS | |
31 | .nf | |
5f1f495c | 32 | .B #include <math.h> |
f90f031e | 33 | .PP |
5f1f495c | 34 | .BI "int matherr(struct exception *" exc ); |
f90f031e | 35 | .PP |
5f1f495c MK |
36 | .B extern _LIB_VERSION_TYPE _LIB_VERSION; |
37 | .fi | |
68e4db0a | 38 | .PP |
5f1f495c MK |
39 | Link with \fI\-lm\fP. |
40 | .SH DESCRIPTION | |
73593f0d MK |
41 | .IR Note : |
42 | the mechanism described in this page is no longer supported by glibc. | |
43 | Before glibc 2.27, it had been marked as obsolete. | |
44 | Since glibc 2.27, | |
45 | .\" glibc commit 813378e9fe17e029caf627cab76fe23eb46815fa | |
46 | the mechanism has been removed altogether. | |
47 | New applications should use the techniques described in | |
48 | .BR math_error (7) | |
49 | and | |
50 | .BR fenv (3). | |
51 | This page documents the | |
52 | .BR matherr () | |
53 | mechanism as an aid for maintaining and porting older applications. | |
54 | .PP | |
5f1f495c MK |
55 | The System V Interface Definition (SVID) specifies that various |
56 | math functions should invoke a function called | |
57 | .BR matherr () | |
58 | if a math exception is detected. | |
59 | This function is called before the math function returns; | |
60 | after | |
61 | .BR matherr () | |
62 | returns, the system then returns to the math function, | |
63 | which in turn returns to the caller. | |
847e0d88 | 64 | .PP |
5f1f495c MK |
65 | To employ |
66 | .BR matherr (), | |
67 | the programmer must define the | |
68 | .B _SVID_SOURCE | |
e417acb0 MK |
69 | feature test macro |
70 | (before including | |
71 | .I any | |
72 | header files), | |
73 | and assign the value | |
5f1f495c MK |
74 | .B _SVID_ |
75 | to the external variable | |
76 | .BR _LIB_VERSION . | |
847e0d88 | 77 | .PP |
5f1f495c MK |
78 | The system provides a default version of |
79 | .BR matherr (). | |
80 | This version does nothing, and returns zero | |
81 | (see below for the significance of this). | |
82 | The default | |
83 | .BR matherr () | |
84 | can be overridden by a programmer-defined | |
85 | version, which will be invoked when an exception occurs. | |
86 | The function is invoked with one argument, a pointer to an | |
87 | .I exception | |
88 | structure, defined as follows: | |
847e0d88 | 89 | .PP |
5f1f495c | 90 | .in +4n |
b8302363 | 91 | .EX |
5f1f495c MK |
92 | struct exception { |
93 | int type; /* Exception type */ | |
94 | char *name; /* Name of function causing exception */ | |
95 | double arg1; /* 1st argument to function */ | |
96 | double arg2; /* 2nd argument to function */ | |
97 | double retval; /* Function return value */ | |
98 | } | |
b8302363 | 99 | .EE |
5f1f495c MK |
100 | .in |
101 | .PP | |
102 | The | |
103 | .I type | |
104 | field has one of the following values: | |
105 | .TP 12 | |
106 | .B DOMAIN | |
107 | A domain error occurred (the function argument was outside the range | |
108 | for which the function is defined). | |
109 | The return value depends on the function; | |
110 | .I errno | |
111 | is set to | |
112 | .BR EDOM . | |
113 | .TP | |
114 | .B SING | |
115 | A pole error occurred (the function result is an infinity). | |
116 | The return value in most cases is | |
117 | .B HUGE | |
118 | (the largest single precision floating-point number), | |
119 | appropriately signed. | |
120 | In most cases, | |
121 | .I errno | |
122 | is set to | |
123 | .BR EDOM . | |
124 | .TP | |
125 | .B OVERFLOW | |
126 | An overflow occurred. | |
127 | In most cases, the value | |
128 | .B HUGE | |
129 | is returned, and | |
130 | .I errno | |
131 | is set to | |
132 | .BR ERANGE . | |
133 | .TP | |
134 | .B UNDERFLOW | |
135 | An underflow occurred. | |
136 | 0.0 is returned, and | |
137 | .I errno | |
138 | is set to | |
139 | .BR ERANGE . | |
140 | .TP | |
141 | .B TLOSS | |
142 | Total loss of significance. | |
143 | 0.0 is returned, and | |
144 | .I errno | |
145 | is set to | |
146 | .BR ERANGE . | |
147 | .TP | |
148 | .B PLOSS | |
149 | Partial loss of significance. | |
150 | This value is unused on glibc | |
151 | (and many other systems). | |
152 | .PP | |
153 | The | |
154 | .I arg1 | |
155 | and | |
156 | .I arg2 | |
157 | fields are the arguments supplied to the function | |
158 | .RI ( arg2 | |
159 | is undefined for functions that take only one argument). | |
847e0d88 | 160 | .PP |
5f1f495c MK |
161 | The |
162 | .I retval | |
163 | field specifies the return value that the math | |
164 | function will return to its caller. | |
165 | The programmer-defined | |
166 | .BR matherr () | |
167 | can modify this field to change the return value of the math function. | |
847e0d88 | 168 | .PP |
5f1f495c MK |
169 | If the |
170 | .BR matherr () | |
171 | function returns zero, then the system sets | |
172 | .I errno | |
173 | as described above, and may print an error message on standard error | |
174 | (see below). | |
847e0d88 | 175 | .PP |
5f1f495c MK |
176 | If the |
177 | .BR matherr () | |
c7094399 | 178 | function returns a nonzero value, then the system does not set |
5f1f495c MK |
179 | .IR errno , |
180 | and doesn't print an error message. | |
181 | .SS Math functions that employ matherr() | |
182 | The table below lists the functions and circumstances in which | |
183 | .BR matherr () | |
184 | is called. | |
185 | The "Type" column indicates the value assigned to | |
186 | .I exc\->type | |
187 | when calling | |
188 | .BR matherr (). | |
189 | The "Result" column is the default return value assigned to | |
190 | .IR exc\->retval . | |
847e0d88 | 191 | .PP |
5f1f495c MK |
192 | The "Msg?" and "errno" columns describe the default behavior if |
193 | .BR matherr () | |
194 | returns zero. | |
195 | If the "Msg?" columns contains "y", | |
196 | then the system prints an error message on standard error. | |
847e0d88 | 197 | .PP |
5f1f495c | 198 | The table uses the following notations and abbreviations: |
207050fa | 199 | .PP |
5f1f495c MK |
200 | .RS |
201 | .nf | |
5f1f495c MK |
202 | x first argument to function |
203 | y second argument to function | |
204 | fin finite value for argument | |
205 | neg negative value for argument | |
206 | int integral value for argument | |
207 | o/f result overflowed | |
208 | u/f result underflowed | |
209 | |x| absolute value of x | |
210 | X_TLOSS is a constant defined in \fI<math.h>\fP | |
211 | .fi | |
212 | .RE | |
213 | .\" Details below from glibc 2.8's sysdeps/ieee754/k_standard.c | |
214 | .\" A subset of cases were test by experimental programs. | |
215 | .TS | |
216 | lB lB lB cB lB | |
217 | l l l c l. | |
218 | Function Type Result Msg? errno | |
219 | acos(|x|>1) DOMAIN HUGE y EDOM | |
220 | asin(|x|>1) DOMAIN HUGE y EDOM | |
221 | atan2(0,0) DOMAIN HUGE y EDOM | |
27844710 MK |
222 | acosh(x<1) DOMAIN NAN y EDOM \" retval is 0.0/0.0 |
223 | atanh(|x|>1) DOMAIN NAN y EDOM \" retval is 0.0/0.0 | |
224 | atanh(|x|==1) SING (x>0.0)? y EDOM \" retval is x/0.0 | |
5f1f495c MK |
225 | \ \ HUGE_VAL : |
226 | \ \ \-HUGE_VAL | |
227 | cosh(fin) o/f OVERFLOW HUGE n ERANGE | |
228 | sinh(fin) o/f OVERFLOW (x>0.0) ? n ERANGE | |
229 | \ \ HUGE : \-HUGE | |
230 | sqrt(x<0) DOMAIN 0.0 y EDOM | |
231 | hypot(fin,fin) o/f OVERFLOW HUGE n ERANGE | |
232 | exp(fin) o/f OVERFLOW HUGE n ERANGE | |
233 | exp(fin) u/f UNDERFLOW 0.0 n ERANGE | |
234 | exp2(fin) o/f OVERFLOW HUGE n ERANGE | |
235 | exp2(fin) u/f UNDERFLOW 0.0 n ERANGE | |
236 | exp10(fin) o/f OVERFLOW HUGE n ERANGE | |
237 | exp10(fin) u/f UNDERFLOW 0.0 n ERANGE | |
238 | j0(|x|>X_TLOSS) TLOSS 0.0 y ERANGE | |
239 | j1(|x|>X_TLOSS) TLOSS 0.0 y ERANGE | |
240 | jn(|x|>X_TLOSS) TLOSS 0.0 y ERANGE | |
241 | y0(x>X_TLOSS) TLOSS 0.0 y ERANGE | |
242 | y1(x>X_TLOSS) TLOSS 0.0 y ERANGE | |
243 | yn(x>X_TLOSS) TLOSS 0.0 y ERANGE | |
244 | y0(0) DOMAIN \-HUGE y EDOM | |
245 | y0(x<0) DOMAIN \-HUGE y EDOM | |
246 | y1(0) DOMAIN \-HUGE y EDOM | |
247 | y1(x<0) DOMAIN \-HUGE y EDOM | |
248 | yn(n,0) DOMAIN \-HUGE y EDOM | |
249 | yn(x<0) DOMAIN \-HUGE y EDOM | |
250 | lgamma(fin) o/f OVERFLOW HUGE n ERANGE | |
251 | lgamma(\-int) or SING HUGE y EDOM | |
252 | \ \ lgamma(0) | |
253 | tgamma(fin) o/f OVERFLOW HUGE_VAL n ERANGE | |
254 | tgamma(\-int) SING NAN y EDOM | |
255 | tgamma(0) SING copysign( y ERANGE | |
256 | \ \ HUGE_VAL,x) | |
257 | log(0) SING \-HUGE y EDOM | |
258 | log(x<0) DOMAIN \-HUGE y EDOM | |
259 | log2(0) SING \-HUGE n EDOM \" different from log() | |
c3074d70 | 260 | log2(x<0) DOMAIN \-HUGE n EDOM \" different from log() |
5f1f495c MK |
261 | log10(0) SING \-HUGE y EDOM |
262 | log10(x<0) DOMAIN \-HUGE y EDOM | |
263 | pow(0.0,0.0) DOMAIN 0.0 y EDOM | |
264 | pow(x,y) o/f OVERFLOW HUGE n ERANGE | |
265 | pow(x,y) u/f UNDERFLOW 0.0 n ERANGE | |
266 | pow(NaN,0.0) DOMAIN x n EDOM | |
267 | 0**neg DOMAIN 0.0 y EDOM \" +0 and -0 | |
268 | neg**non-int DOMAIN 0.0 y EDOM | |
269 | scalb() o/f OVERFLOW (x>0.0) ? n ERANGE | |
270 | \ \ HUGE_VAL : | |
271 | \ \ \-HUGE_VAL | |
272 | scalb() u/f UNDERFLOW copysign( n ERANGE | |
273 | \ \ \ \ 0.0,x) | |
274 | fmod(x,0) DOMAIN x y EDOM | |
27844710 | 275 | remainder(x,0) DOMAIN NAN y EDOM \" retval is 0.0/0.0 |
5f1f495c | 276 | .TE |
d79dfbf6 | 277 | .SH ATTRIBUTES |
3c461ccc PH |
278 | For an explanation of the terms used in this section, see |
279 | .BR attributes (7). | |
280 | .TS | |
281 | allbox; | |
282 | lb lb lb | |
283 | l l l. | |
284 | Interface Attribute Value | |
285 | T{ | |
d79dfbf6 | 286 | .BR matherr () |
3c461ccc PH |
287 | T} Thread safety MT-Safe |
288 | .TE | |
5f1f495c MK |
289 | .SH EXAMPLE |
290 | The example program demonstrates the use of | |
291 | .BR matherr () | |
292 | when calling | |
293 | .BR log (3). | |
294 | The program takes up to three command-line arguments. | |
295 | The first argument is the floating-point number to be given to | |
296 | .BR log (3). | |
297 | If the optional second argument is provided, then | |
298 | .B _LIB_VERSION | |
299 | is set to | |
300 | .B _SVID_ | |
301 | so that | |
302 | .BR matherr () | |
303 | is called, and the integer supplied in the | |
304 | command-line argument is used as the return value from | |
305 | .BR matherr (). | |
306 | If the optional third command-line argument is supplied, | |
307 | then it specifies an alternative return value that | |
308 | .BR matherr () | |
309 | should assign as the return value of the math function. | |
847e0d88 | 310 | .PP |
5f1f495c MK |
311 | The following example run, where |
312 | .BR log (3) | |
313 | is given an argument of 0.0, does not use | |
b18e759d | 314 | .BR matherr (): |
847e0d88 | 315 | .PP |
5f1f495c | 316 | .in +4n |
b8302363 | 317 | .EX |
b43a3b30 | 318 | .RB "$" " ./a.out 0.0" |
5f1f495c MK |
319 | errno: Numerical result out of range |
320 | x=-inf | |
b8302363 | 321 | .EE |
5f1f495c | 322 | .in |
847e0d88 | 323 | .PP |
5f1f495c MK |
324 | In the following run, |
325 | .BR matherr () | |
326 | is called, and returns 0: | |
847e0d88 | 327 | .PP |
5f1f495c | 328 | .in +4n |
b8302363 | 329 | .EX |
b43a3b30 | 330 | .RB "$" " ./a.out 0.0 0" |
5f1f495c MK |
331 | matherr SING exception in log() function |
332 | args: 0.000000, 0.000000 | |
c3074d70 | 333 | retval: \-340282346638528859811704183484516925440.000000 |
5f1f495c MK |
334 | log: SING error |
335 | errno: Numerical argument out of domain | |
336 | x=-340282346638528859811704183484516925440.000000 | |
b8302363 | 337 | .EE |
5f1f495c | 338 | .in |
847e0d88 | 339 | .PP |
5f1f495c | 340 | The message "log: SING error" was printed by the C library. |
847e0d88 | 341 | .PP |
5f1f495c MK |
342 | In the following run, |
343 | .BR matherr () | |
c7094399 | 344 | is called, and returns a nonzero value: |
847e0d88 | 345 | .PP |
5f1f495c | 346 | .in +4n |
b8302363 | 347 | .EX |
b43a3b30 | 348 | .RB "$" " ./a.out 0.0 1" |
5f1f495c MK |
349 | matherr SING exception in log() function |
350 | args: 0.000000, 0.000000 | |
c3074d70 | 351 | retval: \-340282346638528859811704183484516925440.000000 |
5f1f495c | 352 | x=-340282346638528859811704183484516925440.000000 |
b8302363 | 353 | .EE |
5f1f495c | 354 | .in |
847e0d88 | 355 | .PP |
5f1f495c MK |
356 | In this case, the C library did not print a message, and |
357 | .I errno | |
358 | was not set. | |
847e0d88 | 359 | .PP |
5f1f495c MK |
360 | In the following run, |
361 | .BR matherr () | |
362 | is called, changes the return value of the math function, | |
c7094399 | 363 | and returns a nonzero value: |
847e0d88 | 364 | .PP |
5f1f495c | 365 | .in +4n |
b8302363 | 366 | .EX |
b43a3b30 | 367 | .RB "$" " ./a.out 0.0 1 12345.0" |
5f1f495c MK |
368 | matherr SING exception in log() function |
369 | args: 0.000000, 0.000000 | |
c3074d70 | 370 | retval: \-340282346638528859811704183484516925440.000000 |
5f1f495c | 371 | x=12345.000000 |
b8302363 | 372 | .EE |
5f1f495c | 373 | .in |
9c330504 | 374 | .SS Program source |
d84d0300 | 375 | \& |
e7d0bb47 | 376 | .EX |
5f1f495c MK |
377 | #define _SVID_SOURCE |
378 | #include <errno.h> | |
379 | #include <math.h> | |
380 | #include <stdio.h> | |
381 | #include <stdlib.h> | |
382 | ||
383 | static int matherr_ret = 0; /* Value that matherr() | |
384 | should return */ | |
385 | static int change_retval = 0; /* Should matherr() change | |
386 | function\(aqs return value? */ | |
387 | static double new_retval; /* New function return value */ | |
388 | ||
389 | int | |
390 | matherr(struct exception *exc) | |
391 | { | |
d1a71985 | 392 | fprintf(stderr, "matherr %s exception in %s() function\en", |
5f1f495c MK |
393 | (exc\->type == DOMAIN) ? "DOMAIN" : |
394 | (exc\->type == OVERFLOW) ? "OVERFLOW" : | |
395 | (exc\->type == UNDERFLOW) ? "UNDERFLOW" : | |
396 | (exc\->type == SING) ? "SING" : | |
397 | (exc\->type == TLOSS) ? "TLOSS" : | |
398 | (exc\->type == PLOSS) ? "PLOSS" : "???", | |
399 | exc\->name); | |
d1a71985 | 400 | fprintf(stderr, " args: %f, %f\en", |
72da9ef1 | 401 | exc\->arg1, exc\->arg2); |
d1a71985 | 402 | fprintf(stderr, " retval: %f\en", exc\->retval); |
5f1f495c MK |
403 | |
404 | if (change_retval) | |
405 | exc\->retval = new_retval; | |
406 | ||
407 | return matherr_ret; | |
408 | } | |
409 | ||
410 | int | |
411 | main(int argc, char *argv[]) | |
412 | { | |
413 | double x; | |
414 | ||
415 | if (argc < 2) { | |
416 | fprintf(stderr, "Usage: %s <argval>" | |
d1a71985 | 417 | " [<matherr\-ret> [<new\-func\-retval>]]\en", argv[0]); |
5f1f495c MK |
418 | exit(EXIT_FAILURE); |
419 | } | |
420 | ||
421 | if (argc > 2) { | |
422 | _LIB_VERSION = _SVID_; | |
423 | matherr_ret = atoi(argv[2]); | |
424 | } | |
425 | ||
426 | if (argc > 3) { | |
427 | change_retval = 1; | |
428 | new_retval = atof(argv[3]); | |
429 | } | |
430 | ||
431 | x = log(atof(argv[1])); | |
432 | if (errno != 0) | |
433 | perror("errno"); | |
434 | ||
d1a71985 | 435 | printf("x=%f\en", x); |
5f1f495c MK |
436 | exit(EXIT_SUCCESS); |
437 | } | |
e7d0bb47 | 438 | .EE |
5f1f495c | 439 | .SH SEE ALSO |
5f1f495c MK |
440 | .BR fenv (3), |
441 | .BR math_error (7), | |
442 | .BR standards (7) |