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