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