| .\" Copyright (c) 2008, Linux Foundation, written by Michael Kerrisk |
| .\" <mtk.manpages@gmail.com> |
| .\" |
| .\" %%%LICENSE_START(VERBATIM) |
| .\" Permission is granted to make and distribute verbatim copies of this |
| .\" manual provided the copyright notice and this permission notice are |
| .\" preserved on all copies. |
| .\" |
| .\" Permission is granted to copy and distribute modified versions of this |
| .\" manual under the conditions for verbatim copying, provided that the |
| .\" entire resulting derived work is distributed under the terms of a |
| .\" permission notice identical to this one. |
| .\" |
| .\" Since the Linux kernel and libraries are constantly changing, this |
| .\" manual page may be incorrect or out-of-date. The author(s) assume no |
| .\" responsibility for errors or omissions, or for damages resulting from |
| .\" the use of the information contained herein. The author(s) may not |
| .\" have taken the same level of care in the production of this manual, |
| .\" which is licensed free of charge, as they might when working |
| .\" professionally. |
| .\" |
| .\" Formatted or processed versions of this manual, if unaccompanied by |
| .\" the source, must acknowledge the copyright and authors of this work. |
| .\" %%%LICENSE_END |
| .\" |
| .TH MATHERR 3 2021-03-22 "Linux" "Linux Programmer's Manual" |
| .SH NAME |
| matherr \- SVID math library exception handling |
| .SH SYNOPSIS |
| .nf |
| .B #include <math.h> |
| .PP |
| .BI "int matherr(struct exception *" exc ); |
| .PP |
| .B extern _LIB_VERSION_TYPE _LIB_VERSION; |
| .fi |
| .PP |
| Link with \fI\-lm\fP. |
| .SH DESCRIPTION |
| .IR Note : |
| the mechanism described in this page is no longer supported by glibc. |
| Before glibc 2.27, it had been marked as obsolete. |
| Since glibc 2.27, |
| .\" glibc commit 813378e9fe17e029caf627cab76fe23eb46815fa |
| the mechanism has been removed altogether. |
| New applications should use the techniques described in |
| .BR math_error (7) |
| and |
| .BR fenv (3). |
| This page documents the |
| .BR matherr () |
| mechanism as an aid for maintaining and porting older applications. |
| .PP |
| The System V Interface Definition (SVID) specifies that various |
| math functions should invoke a function called |
| .BR matherr () |
| if a math exception is detected. |
| This function is called before the math function returns; |
| after |
| .BR matherr () |
| returns, the system then returns to the math function, |
| which in turn returns to the caller. |
| .PP |
| To employ |
| .BR matherr (), |
| the programmer must define the |
| .B _SVID_SOURCE |
| feature test macro |
| (before including |
| .I any |
| header files), |
| and assign the value |
| .B _SVID_ |
| to the external variable |
| .BR _LIB_VERSION . |
| .PP |
| The system provides a default version of |
| .BR matherr (). |
| This version does nothing, and returns zero |
| (see below for the significance of this). |
| The default |
| .BR matherr () |
| can be overridden by a programmer-defined |
| version, which will be invoked when an exception occurs. |
| The function is invoked with one argument, a pointer to an |
| .I exception |
| structure, defined as follows: |
| .PP |
| .in +4n |
| .EX |
| struct exception { |
| int type; /* Exception type */ |
| char *name; /* Name of function causing exception */ |
| double arg1; /* 1st argument to function */ |
| double arg2; /* 2nd argument to function */ |
| double retval; /* Function return value */ |
| } |
| .EE |
| .in |
| .PP |
| The |
| .I type |
| field has one of the following values: |
| .TP 12 |
| .B DOMAIN |
| A domain error occurred (the function argument was outside the range |
| for which the function is defined). |
| The return value depends on the function; |
| .I errno |
| is set to |
| .BR EDOM . |
| .TP |
| .B SING |
| A pole error occurred (the function result is an infinity). |
| The return value in most cases is |
| .B HUGE |
| (the largest single precision floating-point number), |
| appropriately signed. |
| In most cases, |
| .I errno |
| is set to |
| .BR EDOM . |
| .TP |
| .B OVERFLOW |
| An overflow occurred. |
| In most cases, the value |
| .B HUGE |
| is returned, and |
| .I errno |
| is set to |
| .BR ERANGE . |
| .TP |
| .B UNDERFLOW |
| An underflow occurred. |
| 0.0 is returned, and |
| .I errno |
| is set to |
| .BR ERANGE . |
| .TP |
| .B TLOSS |
| Total loss of significance. |
| 0.0 is returned, and |
| .I errno |
| is set to |
| .BR ERANGE . |
| .TP |
| .B PLOSS |
| Partial loss of significance. |
| This value is unused on glibc |
| (and many other systems). |
| .PP |
| The |
| .I arg1 |
| and |
| .I arg2 |
| fields are the arguments supplied to the function |
| .RI ( arg2 |
| is undefined for functions that take only one argument). |
| .PP |
| The |
| .I retval |
| field specifies the return value that the math |
| function will return to its caller. |
| The programmer-defined |
| .BR matherr () |
| can modify this field to change the return value of the math function. |
| .PP |
| If the |
| .BR matherr () |
| function returns zero, then the system sets |
| .I errno |
| as described above, and may print an error message on standard error |
| (see below). |
| .PP |
| If the |
| .BR matherr () |
| function returns a nonzero value, then the system does not set |
| .IR errno , |
| and doesn't print an error message. |
| .SS Math functions that employ matherr() |
| The table below lists the functions and circumstances in which |
| .BR matherr () |
| is called. |
| The "Type" column indicates the value assigned to |
| .I exc\->type |
| when calling |
| .BR matherr (). |
| The "Result" column is the default return value assigned to |
| .IR exc\->retval . |
| .PP |
| The "Msg?" and "errno" columns describe the default behavior if |
| .BR matherr () |
| returns zero. |
| If the "Msg?" columns contains "y", |
| then the system prints an error message on standard error. |
| .PP |
| The table uses the following notations and abbreviations: |
| .PP |
| .RS |
| .TS |
| l l. |
| x first argument to function |
| y second argument to function |
| fin finite value for argument |
| neg negative value for argument |
| int integral value for argument |
| o/f result overflowed |
| u/f result underflowed |
| |x| absolute value of x |
| X_TLOSS is a constant defined in \fI<math.h>\fP |
| .TE |
| .RE |
| .\" Details below from glibc 2.8's sysdeps/ieee754/k_standard.c |
| .\" A subset of cases were test by experimental programs. |
| .TS |
| lB lB lB cB lB |
| l l l c l. |
| Function Type Result Msg? errno |
| acos(|x|>1) DOMAIN HUGE y EDOM |
| asin(|x|>1) DOMAIN HUGE y EDOM |
| atan2(0,0) DOMAIN HUGE y EDOM |
| acosh(x<1) DOMAIN NAN y EDOM \" retval is 0.0/0.0 |
| atanh(|x|>1) DOMAIN NAN y EDOM \" retval is 0.0/0.0 |
| atanh(|x|==1) SING (x>0.0)? y EDOM \" retval is x/0.0 |
| \ \ HUGE_VAL : |
| \ \ \-HUGE_VAL |
| cosh(fin) o/f OVERFLOW HUGE n ERANGE |
| sinh(fin) o/f OVERFLOW (x>0.0) ? n ERANGE |
| \ \ HUGE : \-HUGE |
| sqrt(x<0) DOMAIN 0.0 y EDOM |
| hypot(fin,fin) o/f OVERFLOW HUGE n ERANGE |
| exp(fin) o/f OVERFLOW HUGE n ERANGE |
| exp(fin) u/f UNDERFLOW 0.0 n ERANGE |
| exp2(fin) o/f OVERFLOW HUGE n ERANGE |
| exp2(fin) u/f UNDERFLOW 0.0 n ERANGE |
| exp10(fin) o/f OVERFLOW HUGE n ERANGE |
| exp10(fin) u/f UNDERFLOW 0.0 n ERANGE |
| j0(|x|>X_TLOSS) TLOSS 0.0 y ERANGE |
| j1(|x|>X_TLOSS) TLOSS 0.0 y ERANGE |
| jn(|x|>X_TLOSS) TLOSS 0.0 y ERANGE |
| y0(x>X_TLOSS) TLOSS 0.0 y ERANGE |
| y1(x>X_TLOSS) TLOSS 0.0 y ERANGE |
| yn(x>X_TLOSS) TLOSS 0.0 y ERANGE |
| y0(0) DOMAIN \-HUGE y EDOM |
| y0(x<0) DOMAIN \-HUGE y EDOM |
| y1(0) DOMAIN \-HUGE y EDOM |
| y1(x<0) DOMAIN \-HUGE y EDOM |
| yn(n,0) DOMAIN \-HUGE y EDOM |
| yn(x<0) DOMAIN \-HUGE y EDOM |
| lgamma(fin) o/f OVERFLOW HUGE n ERANGE |
| lgamma(\-int) or SING HUGE y EDOM |
| \ \ lgamma(0) |
| tgamma(fin) o/f OVERFLOW HUGE_VAL n ERANGE |
| tgamma(\-int) SING NAN y EDOM |
| tgamma(0) SING copysign( y ERANGE |
| \ \ HUGE_VAL,x) |
| log(0) SING \-HUGE y EDOM |
| log(x<0) DOMAIN \-HUGE y EDOM |
| log2(0) SING \-HUGE n EDOM \" different from log() |
| log2(x<0) DOMAIN \-HUGE n EDOM \" different from log() |
| log10(0) SING \-HUGE y EDOM |
| log10(x<0) DOMAIN \-HUGE y EDOM |
| pow(0.0,0.0) DOMAIN 0.0 y EDOM |
| pow(x,y) o/f OVERFLOW HUGE n ERANGE |
| pow(x,y) u/f UNDERFLOW 0.0 n ERANGE |
| pow(NaN,0.0) DOMAIN x n EDOM |
| 0**neg DOMAIN 0.0 y EDOM \" +0 and -0 |
| neg**non-int DOMAIN 0.0 y EDOM |
| scalb() o/f OVERFLOW (x>0.0) ? n ERANGE |
| \ \ HUGE_VAL : |
| \ \ \-HUGE_VAL |
| scalb() u/f UNDERFLOW copysign( n ERANGE |
| \ \ \ \ 0.0,x) |
| fmod(x,0) DOMAIN x y EDOM |
| remainder(x,0) DOMAIN NAN y EDOM \" retval is 0.0/0.0 |
| .TE |
| .SH ATTRIBUTES |
| For an explanation of the terms used in this section, see |
| .BR attributes (7). |
| .ad l |
| .nh |
| .TS |
| allbox; |
| lbx lb lb |
| l l l. |
| Interface Attribute Value |
| T{ |
| .BR matherr () |
| T} Thread safety MT-Safe |
| .TE |
| .hy |
| .ad |
| .sp 1 |
| .SH EXAMPLES |
| The example program demonstrates the use of |
| .BR matherr () |
| when calling |
| .BR log (3). |
| The program takes up to three command-line arguments. |
| The first argument is the floating-point number to be given to |
| .BR log (3). |
| If the optional second argument is provided, then |
| .B _LIB_VERSION |
| is set to |
| .B _SVID_ |
| so that |
| .BR matherr () |
| is called, and the integer supplied in the |
| command-line argument is used as the return value from |
| .BR matherr (). |
| If the optional third command-line argument is supplied, |
| then it specifies an alternative return value that |
| .BR matherr () |
| should assign as the return value of the math function. |
| .PP |
| The following example run, where |
| .BR log (3) |
| is given an argument of 0.0, does not use |
| .BR matherr (): |
| .PP |
| .in +4n |
| .EX |
| .RB "$" " ./a.out 0.0" |
| errno: Numerical result out of range |
| x=\-inf |
| .EE |
| .in |
| .PP |
| In the following run, |
| .BR matherr () |
| is called, and returns 0: |
| .PP |
| .in +4n |
| .EX |
| .RB "$" " ./a.out 0.0 0" |
| matherr SING exception in log() function |
| args: 0.000000, 0.000000 |
| retval: \-340282346638528859811704183484516925440.000000 |
| log: SING error |
| errno: Numerical argument out of domain |
| x=\-340282346638528859811704183484516925440.000000 |
| .EE |
| .in |
| .PP |
| The message "log: SING error" was printed by the C library. |
| .PP |
| In the following run, |
| .BR matherr () |
| is called, and returns a nonzero value: |
| .PP |
| .in +4n |
| .EX |
| .RB "$" " ./a.out 0.0 1" |
| matherr SING exception in log() function |
| args: 0.000000, 0.000000 |
| retval: \-340282346638528859811704183484516925440.000000 |
| x=\-340282346638528859811704183484516925440.000000 |
| .EE |
| .in |
| .PP |
| In this case, the C library did not print a message, and |
| .I errno |
| was not set. |
| .PP |
| In the following run, |
| .BR matherr () |
| is called, changes the return value of the math function, |
| and returns a nonzero value: |
| .PP |
| .in +4n |
| .EX |
| .RB "$" " ./a.out 0.0 1 12345.0" |
| matherr SING exception in log() function |
| args: 0.000000, 0.000000 |
| retval: \-340282346638528859811704183484516925440.000000 |
| x=12345.000000 |
| .EE |
| .in |
| .SS Program source |
| \& |
| .EX |
| #define _SVID_SOURCE |
| #include <errno.h> |
| #include <math.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| static int matherr_ret = 0; /* Value that matherr() |
| should return */ |
| static int change_retval = 0; /* Should matherr() change |
| function\(aqs return value? */ |
| static double new_retval; /* New function return value */ |
| |
| int |
| matherr(struct exception *exc) |
| { |
| fprintf(stderr, "matherr %s exception in %s() function\en", |
| (exc\->type == DOMAIN) ? "DOMAIN" : |
| (exc\->type == OVERFLOW) ? "OVERFLOW" : |
| (exc\->type == UNDERFLOW) ? "UNDERFLOW" : |
| (exc\->type == SING) ? "SING" : |
| (exc\->type == TLOSS) ? "TLOSS" : |
| (exc\->type == PLOSS) ? "PLOSS" : "???", |
| exc\->name); |
| fprintf(stderr, " args: %f, %f\en", |
| exc\->arg1, exc\->arg2); |
| fprintf(stderr, " retval: %f\en", exc\->retval); |
| |
| if (change_retval) |
| exc\->retval = new_retval; |
| |
| return matherr_ret; |
| } |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| double x; |
| |
| if (argc < 2) { |
| fprintf(stderr, "Usage: %s <argval>" |
| " [<matherr\-ret> [<new\-func\-retval>]]\en", argv[0]); |
| exit(EXIT_FAILURE); |
| } |
| |
| if (argc > 2) { |
| _LIB_VERSION = _SVID_; |
| matherr_ret = atoi(argv[2]); |
| } |
| |
| if (argc > 3) { |
| change_retval = 1; |
| new_retval = atof(argv[3]); |
| } |
| |
| x = log(atof(argv[1])); |
| if (errno != 0) |
| perror("errno"); |
| |
| printf("x=%f\en", x); |
| exit(EXIT_SUCCESS); |
| } |
| .EE |
| .SH SEE ALSO |
| .BR fenv (3), |
| .BR math_error (7), |
| .BR standards (7) |