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