xref: /freebsd-src/lib/msun/man/fenv.3 (revision fa9896e082a1046ff4fbc75fcba4d18d1f2efc19)
107235cc8SDavid Schultz.\" Copyright (c) 2004 David Schultz <das@FreeBSD.org>
207235cc8SDavid Schultz.\" All rights reserved.
307235cc8SDavid Schultz.\"
407235cc8SDavid Schultz.\" Redistribution and use in source and binary forms, with or without
507235cc8SDavid Schultz.\" modification, are permitted provided that the following conditions
607235cc8SDavid Schultz.\" are met:
707235cc8SDavid Schultz.\" 1. Redistributions of source code must retain the above copyright
807235cc8SDavid Schultz.\"    notice, this list of conditions and the following disclaimer.
907235cc8SDavid Schultz.\" 2. Redistributions in binary form must reproduce the above copyright
1007235cc8SDavid Schultz.\"    notice, this list of conditions and the following disclaimer in the
1107235cc8SDavid Schultz.\"    documentation and/or other materials provided with the distribution.
1207235cc8SDavid Schultz.\"
1307235cc8SDavid Schultz.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1407235cc8SDavid Schultz.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1507235cc8SDavid Schultz.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1607235cc8SDavid Schultz.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1707235cc8SDavid Schultz.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1807235cc8SDavid Schultz.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1907235cc8SDavid Schultz.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2007235cc8SDavid Schultz.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2107235cc8SDavid Schultz.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2207235cc8SDavid Schultz.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2307235cc8SDavid Schultz.\" SUCH DAMAGE.
2407235cc8SDavid Schultz.\"
2510b01832SDavid Schultz.Dd March 16, 2005
2607235cc8SDavid Schultz.Dt FENV 3
2707235cc8SDavid Schultz.Os
2807235cc8SDavid Schultz.Sh NAME
2907235cc8SDavid Schultz.Nm feclearexcept ,
3007235cc8SDavid Schultz.Nm fegetexceptflag ,
3107235cc8SDavid Schultz.Nm feraiseexcept ,
3207235cc8SDavid Schultz.Nm fesetexceptflag ,
3307235cc8SDavid Schultz.Nm fetestexcept ,
3407235cc8SDavid Schultz.Nm fegetround ,
3507235cc8SDavid Schultz.Nm fesetround ,
3607235cc8SDavid Schultz.Nm fegetenv ,
3707235cc8SDavid Schultz.Nm feholdexcept ,
3807235cc8SDavid Schultz.Nm fesetenv ,
3910b01832SDavid Schultz.Nm feupdateenv ,
4010b01832SDavid Schultz.Nm feenableexcept ,
4110b01832SDavid Schultz.Nm fedisableexcept ,
4210b01832SDavid Schultz.Nm fegetexcept
4307235cc8SDavid Schultz.Nd floating-point environment control
4407235cc8SDavid Schultz.Sh LIBRARY
4507235cc8SDavid Schultz.Lb libm
4607235cc8SDavid Schultz.Sh SYNOPSIS
4707235cc8SDavid Schultz.In fenv.h
4807235cc8SDavid Schultz.Fd "#pragma STDC FENV_ACCESS ON"
4907235cc8SDavid Schultz.Ft int
5007235cc8SDavid Schultz.Fn feclearexcept "int excepts"
5107235cc8SDavid Schultz.Ft int
5207235cc8SDavid Schultz.Fn fegetexceptflag "fexcept_t *flagp" "int excepts"
5307235cc8SDavid Schultz.Ft int
5407235cc8SDavid Schultz.Fn feraiseexcept "int excepts"
5507235cc8SDavid Schultz.Ft int
5607235cc8SDavid Schultz.Fn fesetexceptflag "const fexcept_t *flagp" "int excepts"
5707235cc8SDavid Schultz.Ft int
5807235cc8SDavid Schultz.Fn fetestexcept "int excepts"
5907235cc8SDavid Schultz.Ft int
60e880667bSRuslan Ermilov.Fn fegetround void
6107235cc8SDavid Schultz.Ft int
6207235cc8SDavid Schultz.Fn fesetround "int round"
6307235cc8SDavid Schultz.Ft int
6407235cc8SDavid Schultz.Fn fegetenv "fenv_t *envp"
6507235cc8SDavid Schultz.Ft int
6607235cc8SDavid Schultz.Fn feholdexcept "fenv_t *envp"
6707235cc8SDavid Schultz.Ft int
6807235cc8SDavid Schultz.Fn fesetenv "const fenv_t *envp"
6907235cc8SDavid Schultz.Ft int
7007235cc8SDavid Schultz.Fn feupdateenv "const fenv_t *envp"
7110b01832SDavid Schultz.Ft int
7210b01832SDavid Schultz.Fn feenableexcept "int excepts"
7310b01832SDavid Schultz.Ft int
7410b01832SDavid Schultz.Fn fedisableexcept "int excepts"
7510b01832SDavid Schultz.Ft int
76f789cb82SRuslan Ermilov.Fn fegetexcept void
7707235cc8SDavid Schultz.Sh DESCRIPTION
78e880667bSRuslan ErmilovThe
79e880667bSRuslan Ermilov.In fenv.h
80e880667bSRuslan Ermilovroutines manipulate the floating-point environment,
8107235cc8SDavid Schultzwhich includes the exception flags and rounding modes defined in
8207235cc8SDavid Schultz.St -ieee754 .
8307235cc8SDavid Schultz.Ss Exceptions
8407235cc8SDavid SchultzException flags are set as side-effects of floating-point arithmetic
8507235cc8SDavid Schultzoperations and math library routines, and they remain set until
8607235cc8SDavid Schultzexplicitly cleared.
8707235cc8SDavid SchultzThe following macros expand to bit flags of type
8807235cc8SDavid Schultz.Vt int
8907235cc8SDavid Schultzrepresenting the five standard floating-point exceptions.
9007235cc8SDavid Schultz.Bl -tag -width ".Dv FE_DIVBYZERO"
91e880667bSRuslan Ermilov.It Dv FE_DIVBYZERO
92*1f52bcddSDavid SchultzA divide-by-zero exception occurs when the
93*1f52bcddSDavid Schultz.Em exact
94*1f52bcddSDavid Schultzresult of a computation is infinite (according to the limit definition).
95*1f52bcddSDavid SchultzFor example, dividing a finite non-zero number by zero or computing
96*1f52bcddSDavid Schultz.Fn log 0
97*1f52bcddSDavid Schultzraises a divide-by-zero exception.
98e880667bSRuslan Ermilov.It Dv FE_INEXACT
99*1f52bcddSDavid SchultzAn inexact exception is raised whenever there is a loss of accuracy
10007235cc8SDavid Schultzdue to rounding.
101e880667bSRuslan Ermilov.It Dv FE_INVALID
10207235cc8SDavid SchultzInvalid operation exceptions occur when a program attempts to
10307235cc8SDavid Schultzperform calculations for which there is no reasonable representable
10407235cc8SDavid Schultzanswer.
105*1f52bcddSDavid SchultzFor instance, subtraction of like-signed infinities, division of zero by zero,
106*1f52bcddSDavid Schultzordered comparison involving \*(Nas, and taking the real square root of a
10707235cc8SDavid Schultznegative number are all invalid operations.
108e880667bSRuslan Ermilov.It Dv FE_OVERFLOW
109*1f52bcddSDavid SchultzIn contrast with divide-by-zero,
110*1f52bcddSDavid Schultzan overflow exception occurs when an infinity is produced because
111*1f52bcddSDavid Schultzthe magnitude of the exact result is
112*1f52bcddSDavid Schultz.Em finite
113*1f52bcddSDavid Schultzbut too large to fit in the destination type.
114*1f52bcddSDavid SchultzFor example, computing
115*1f52bcddSDavid Schultz.Li DBL_MAX * 2
116*1f52bcddSDavid Schultzraises an overflow exception.
117e880667bSRuslan Ermilov.It Dv FE_UNDERFLOW
118*1f52bcddSDavid SchultzUnderflow occurs when the result of a computation loses precision
119*1f52bcddSDavid Schultzbecause it is too close to zero.
120*1f52bcddSDavid SchultzThe result is a subnormal number or zero.
12107235cc8SDavid Schultz.El
12207235cc8SDavid Schultz.Pp
12307235cc8SDavid SchultzAdditionally, the
12407235cc8SDavid Schultz.Dv FE_ALL_EXCEPT
12507235cc8SDavid Schultzmacro expands to the bitwise OR of the above flags and any
12607235cc8SDavid Schultzarchitecture-specific flags.
12707235cc8SDavid SchultzCombinations of these flags are passed to the
12807235cc8SDavid Schultz.Fn feclearexcept ,
12907235cc8SDavid Schultz.Fn fegetexceptflag ,
13007235cc8SDavid Schultz.Fn feraiseexcept ,
13107235cc8SDavid Schultz.Fn fesetexceptflag ,
13207235cc8SDavid Schultzand
13307235cc8SDavid Schultz.Fn fetestexcept
13407235cc8SDavid Schultzfunctions to clear, save, raise, restore, and examine the
13507235cc8SDavid Schultzprocessor's floating-point exception flags, respectively.
13610b01832SDavid Schultz.Pp
13710b01832SDavid SchultzExceptions may be
13810b01832SDavid Schultz.Em unmasked
13910b01832SDavid Schultzwith
14010b01832SDavid Schultz.Fn feenableexcept
14110b01832SDavid Schultzand masked with
14210b01832SDavid Schultz.Fn fedisableexcept .
14310b01832SDavid SchultzUnmasked exceptions cause a trap when they are produced, and
14410b01832SDavid Schultzall exceptions are masked by default.
14510b01832SDavid SchultzThe current mask can be tested with
14610b01832SDavid Schultz.Fn fegetexcept .
14707235cc8SDavid Schultz.Ss Rounding Modes
14807235cc8SDavid Schultz.St -ieee754
14907235cc8SDavid Schultzspecifies four rounding modes.
15007235cc8SDavid SchultzThese modes control the direction in which results are rounded
15107235cc8SDavid Schultzfrom their exact values in order to fit them into binary
15207235cc8SDavid Schultzfloating-point variables.
15307235cc8SDavid SchultzThe four modes correspond with the following symbolic constants.
15407235cc8SDavid Schultz.Bl -tag -width ".Dv FE_TOWARDZERO"
155e880667bSRuslan Ermilov.It Dv FE_TONEAREST
15607235cc8SDavid SchultzResults are rounded to the closest representable value.
15707235cc8SDavid SchultzIf the exact result is exactly half way between two representable
15807235cc8SDavid Schultzvalues, the value whose last binary digit is even (zero) is chosen.
15907235cc8SDavid SchultzThis is the default mode.
160e880667bSRuslan Ermilov.It Dv FE_DOWNWARD
16107235cc8SDavid SchultzResults are rounded towards negative \*[If].
162e880667bSRuslan Ermilov.It Dv FE_UPWARD
16307235cc8SDavid SchultzResults are rounded towards positive \*[If].
164e880667bSRuslan Ermilov.It Dv FE_TOWARDZERO
16507235cc8SDavid SchultzResults are rounded towards zero.
16607235cc8SDavid Schultz.El
16707235cc8SDavid Schultz.Pp
16807235cc8SDavid SchultzThe
16907235cc8SDavid Schultz.Fn fegetround
17007235cc8SDavid Schultzand
17107235cc8SDavid Schultz.Fn fesetround
17207235cc8SDavid Schultzfunctions query and set the rounding mode.
17307235cc8SDavid Schultz.Ss Environment Control
17407235cc8SDavid SchultzThe
17507235cc8SDavid Schultz.Fn fegetenv
17607235cc8SDavid Schultzand
17707235cc8SDavid Schultz.Fn fesetenv
17807235cc8SDavid Schultzfunctions save and restore the floating-point environment,
17907235cc8SDavid Schultzwhich includes exception flags, the current exception mask,
18007235cc8SDavid Schultzthe rounding mode, and possibly other implementation-specific
18107235cc8SDavid Schultzstate.
18207235cc8SDavid SchultzThe
18307235cc8SDavid Schultz.Fn feholdexcept
18407235cc8SDavid Schultzfunction behaves like
18507235cc8SDavid Schultz.Fn fegetenv ,
18607235cc8SDavid Schultzbut with the additional effect of clearing the exception flags and
18707235cc8SDavid Schultzinstalling a
18807235cc8SDavid Schultz.Em non-stop
18907235cc8SDavid Schultzmode.
19007235cc8SDavid SchultzIn non-stop mode, floating-point operations will set exception flags
19107235cc8SDavid Schultzas usual, but no
19207235cc8SDavid Schultz.Dv SIGFPE
19307235cc8SDavid Schultzsignals will be generated as a result.
19407235cc8SDavid SchultzNon-stop mode is the default, but it may be altered by
195*1f52bcddSDavid Schultz.Fn feenableexcept
196*1f52bcddSDavid Schultzand
197*1f52bcddSDavid Schultz.Fn fedisableexcept .
19807235cc8SDavid SchultzThe
19907235cc8SDavid Schultz.Fn feupdateenv
20007235cc8SDavid Schultzfunction restores a saved environment similarly to
20107235cc8SDavid Schultz.Fn fesetenv ,
20207235cc8SDavid Schultzbut it also re-raises any floating-point exceptions from the old
20307235cc8SDavid Schultzenvironment.
20407235cc8SDavid Schultz.Pp
20507235cc8SDavid SchultzThe macro
20607235cc8SDavid Schultz.Dv FE_DFL_ENV
20707235cc8SDavid Schultzexpands to a pointer to the default environment.
20807235cc8SDavid Schultz.Sh EXAMPLES
20907235cc8SDavid SchultzThe following routine computes the square root function.
21007235cc8SDavid SchultzIt explicitly raises an invalid exception on appropriate inputs using
21107235cc8SDavid Schultz.Fn feraiseexcept .
21207235cc8SDavid SchultzIt also defers inexact exceptions while it computes intermediate
21307235cc8SDavid Schultzvalues, and then it allows an inexact exception to be raised only if
21407235cc8SDavid Schultzthe final answer is inexact.
21507235cc8SDavid Schultz.Bd -literal -offset indent
21607235cc8SDavid Schultz#pragma STDC FENV_ACCESS ON
21707235cc8SDavid Schultzdouble sqrt(double n) {
21807235cc8SDavid Schultz	double x = 1.0;
21907235cc8SDavid Schultz	fenv_t env;
22007235cc8SDavid Schultz
22107235cc8SDavid Schultz	if (isnan(n) || n < 0.0) {
22207235cc8SDavid Schultz		feraiseexcept(FE_INVALID);
22307235cc8SDavid Schultz		return (NAN);
22407235cc8SDavid Schultz	}
22507235cc8SDavid Schultz	if (isinf(n) || n == 0.0)
22607235cc8SDavid Schultz		return (n);
22707235cc8SDavid Schultz	feholdexcept(&env);
22807235cc8SDavid Schultz	while (fabs((x * x) - n) > DBL_EPSILON * 2 * x)
22907235cc8SDavid Schultz		x = (x / 2) + (n / (2 * x));
23007235cc8SDavid Schultz	if (x * x == n)
23107235cc8SDavid Schultz		feclearexcept(FE_INEXACT);
23207235cc8SDavid Schultz	feupdateenv(&env);
23307235cc8SDavid Schultz	return (x);
23407235cc8SDavid Schultz}
23507235cc8SDavid Schultz.Ed
23607235cc8SDavid Schultz.Sh SEE ALSO
23707235cc8SDavid Schultz.Xr cc 1 ,
23807235cc8SDavid Schultz.Xr feclearexcept 3 ,
23910b01832SDavid Schultz.Xr fedisableexcept 3 ,
24010b01832SDavid Schultz.Xr feenableexcept 3 ,
24107235cc8SDavid Schultz.Xr fegetenv 3 ,
24210b01832SDavid Schultz.Xr fegetexcept 3 ,
24307235cc8SDavid Schultz.Xr fegetexceptflag 3 ,
24407235cc8SDavid Schultz.Xr fegetround 3 ,
24507235cc8SDavid Schultz.Xr feholdexcept 3 ,
24607235cc8SDavid Schultz.Xr feraiseexcept 3 ,
24707235cc8SDavid Schultz.Xr fesetenv 3 ,
24807235cc8SDavid Schultz.Xr fesetexceptflag 3 ,
24907235cc8SDavid Schultz.Xr fesetround 3 ,
25007235cc8SDavid Schultz.Xr fetestexcept 3 ,
25107235cc8SDavid Schultz.Xr feupdateenv 3 ,
25207235cc8SDavid Schultz.Xr fpgetprec 3 ,
25310b01832SDavid Schultz.Xr fpsetprec 3
25407235cc8SDavid Schultz.Sh STANDARDS
25507235cc8SDavid SchultzExcept as noted below,
25607235cc8SDavid Schultz.In fenv.h
25707235cc8SDavid Schultzconforms to
25807235cc8SDavid Schultz.St -isoC-99 .
25910b01832SDavid SchultzThe
26010b01832SDavid Schultz.Fn feenableexcept ,
26110b01832SDavid Schultz.Fn fedisableexcept ,
26210b01832SDavid Schultzand
26310b01832SDavid Schultz.Fn fegetexcept
26410b01832SDavid Schultzroutines are extensions.
26507235cc8SDavid Schultz.Sh HISTORY
26607235cc8SDavid SchultzThe
26707235cc8SDavid Schultz.In fenv.h
26807235cc8SDavid Schultzheader first appeared in
26907235cc8SDavid Schultz.Fx 5.3 .
27007235cc8SDavid SchultzIt supersedes the non-standard routines defined in
27107235cc8SDavid Schultz.In ieeefp.h
27207235cc8SDavid Schultzand documented in
27307235cc8SDavid Schultz.Xr fpgetround 3 .
2740afc94c1SUlrich Spörlein.Sh CAVEATS
2750afc94c1SUlrich SpörleinThe FENV_ACCESS pragma can be enabled with
2760afc94c1SUlrich Spörlein.Dl "#pragma STDC FENV_ACCESS ON"
2770afc94c1SUlrich Spörleinand disabled with the
2780afc94c1SUlrich Spörlein.Dl "#pragma STDC FENV_ACCESS OFF"
2790afc94c1SUlrich Spörleindirective.
2800afc94c1SUlrich SpörleinThis lexically-scoped annotation tells the compiler that the program
2810afc94c1SUlrich Spörleinmay access the floating-point environment, so optimizations that would
2820afc94c1SUlrich Spörleinviolate strict IEEE-754 semantics are disabled.
2830afc94c1SUlrich SpörleinIf execution reaches a block of code for which
2840afc94c1SUlrich Spörlein.Dv FENV_ACCESS
2850afc94c1SUlrich Spörleinis off, the floating-point environment will become undefined.
28607235cc8SDavid Schultz.Sh BUGS
28707235cc8SDavid SchultzThe
28807235cc8SDavid Schultz.Dv FENV_ACCESS
28907235cc8SDavid Schultzpragma is unimplemented in the system compiler.
29007235cc8SDavid SchultzHowever, non-constant expressions generally produce the correct
29107235cc8SDavid Schultzside-effects at low optimization levels.
292