xref: /freebsd/lib/msun/man/fenv.3 (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
1.\" Copyright (c) 2004 David Schultz <das@FreeBSD.org>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\" $FreeBSD$
26.\"
27.Dd March 16, 2005
28.Dt FENV 3
29.Os
30.Sh NAME
31.Nm feclearexcept ,
32.Nm fegetexceptflag ,
33.Nm feraiseexcept ,
34.Nm fesetexceptflag ,
35.Nm fetestexcept ,
36.Nm fegetround ,
37.Nm fesetround ,
38.Nm fegetenv ,
39.Nm feholdexcept ,
40.Nm fesetenv ,
41.Nm feupdateenv ,
42.Nm feenableexcept ,
43.Nm fedisableexcept ,
44.Nm fegetexcept
45.Nd floating-point environment control
46.Sh LIBRARY
47.Lb libm
48.Sh SYNOPSIS
49.In fenv.h
50.Fd "#pragma STDC FENV_ACCESS ON"
51.Ft int
52.Fn feclearexcept "int excepts"
53.Ft int
54.Fn fegetexceptflag "fexcept_t *flagp" "int excepts"
55.Ft int
56.Fn feraiseexcept "int excepts"
57.Ft int
58.Fn fesetexceptflag "const fexcept_t *flagp" "int excepts"
59.Ft int
60.Fn fetestexcept "int excepts"
61.Ft int
62.Fn fegetround void
63.Ft int
64.Fn fesetround "int round"
65.Ft int
66.Fn fegetenv "fenv_t *envp"
67.Ft int
68.Fn feholdexcept "fenv_t *envp"
69.Ft int
70.Fn fesetenv "const fenv_t *envp"
71.Ft int
72.Fn feupdateenv "const fenv_t *envp"
73.Ft int
74.Fn feenableexcept "int excepts"
75.Ft int
76.Fn fedisableexcept "int excepts"
77.Ft int
78.Fn fegetexcept void
79.Sh DESCRIPTION
80The
81.In fenv.h
82routines manipulate the floating-point environment,
83which includes the exception flags and rounding modes defined in
84.St -ieee754 .
85.Ss Exceptions
86Exception flags are set as side-effects of floating-point arithmetic
87operations and math library routines, and they remain set until
88explicitly cleared.
89The following macros expand to bit flags of type
90.Vt int
91representing the five standard floating-point exceptions.
92.Bl -tag -width ".Dv FE_DIVBYZERO"
93.It Dv FE_DIVBYZERO
94A divide-by-zero exception occurs when the program attempts to
95divide a finite non-zero number by zero.
96.It Dv FE_INEXACT
97An inexact exception is raised whenever there is a loss of precision
98due to rounding.
99.It Dv FE_INVALID
100Invalid operation exceptions occur when a program attempts to
101perform calculations for which there is no reasonable representable
102answer.
103For instance, subtraction of infinities, division of zero by zero,
104ordered comparison involving \*(Nas, and taking the square root of a
105negative number are all invalid operations.
106.It Dv FE_OVERFLOW
107An overflow exception occurs when the magnitude of the result of a
108computation is too large to fit in the destination type.
109.It Dv FE_UNDERFLOW
110Underflow occurs when the result of a computation is too close to zero
111to be represented as a non-zero value in the destination type.
112.El
113.Pp
114Additionally, the
115.Dv FE_ALL_EXCEPT
116macro expands to the bitwise OR of the above flags and any
117architecture-specific flags.
118Combinations of these flags are passed to the
119.Fn feclearexcept ,
120.Fn fegetexceptflag ,
121.Fn feraiseexcept ,
122.Fn fesetexceptflag ,
123and
124.Fn fetestexcept
125functions to clear, save, raise, restore, and examine the
126processor's floating-point exception flags, respectively.
127.Pp
128Exceptions may be
129.Em unmasked
130with
131.Fn feenableexcept
132and masked with
133.Fn fedisableexcept .
134Unmasked exceptions cause a trap when they are produced, and
135all exceptions are masked by default.
136The current mask can be tested with
137.Fn fegetexcept .
138.Ss Rounding Modes
139.St -ieee754
140specifies four rounding modes.
141These modes control the direction in which results are rounded
142from their exact values in order to fit them into binary
143floating-point variables.
144The four modes correspond with the following symbolic constants.
145.Bl -tag -width ".Dv FE_TOWARDZERO"
146.It Dv FE_TONEAREST
147Results are rounded to the closest representable value.
148If the exact result is exactly half way between two representable
149values, the value whose last binary digit is even (zero) is chosen.
150This is the default mode.
151.It Dv FE_DOWNWARD
152Results are rounded towards negative \*[If].
153.It Dv FE_UPWARD
154Results are rounded towards positive \*[If].
155.It Dv FE_TOWARDZERO
156Results are rounded towards zero.
157.El
158.Pp
159The
160.Fn fegetround
161and
162.Fn fesetround
163functions query and set the rounding mode.
164.Ss Environment Control
165The
166.Fn fegetenv
167and
168.Fn fesetenv
169functions save and restore the floating-point environment,
170which includes exception flags, the current exception mask,
171the rounding mode, and possibly other implementation-specific
172state.
173The
174.Fn feholdexcept
175function behaves like
176.Fn fegetenv ,
177but with the additional effect of clearing the exception flags and
178installing a
179.Em non-stop
180mode.
181In non-stop mode, floating-point operations will set exception flags
182as usual, but no
183.Dv SIGFPE
184signals will be generated as a result.
185Non-stop mode is the default, but it may be altered by
186non-standard mechanisms.
187.\" XXX Mention fe[gs]etmask() here after the interface is finalized
188.\" XXX and ready to be officially documented.
189The
190.Fn feupdateenv
191function restores a saved environment similarly to
192.Fn fesetenv ,
193but it also re-raises any floating-point exceptions from the old
194environment.
195.Pp
196The macro
197.Dv FE_DFL_ENV
198expands to a pointer to the default environment.
199.Sh CAVEATS
200The FENV_ACCESS pragma can be enabled with
201.Dl "#pragma STDC FENV_ACCESS ON"
202and disabled with the
203.Dl "#pragma STDC FENV_ACCESS OFF"
204directive.
205This lexically-scoped annotation tells the compiler that the program
206may access the floating-point environment, so optimizations that would
207violate strict IEEE-754 semantics are disabled.
208If execution reaches a block of code for which
209.Dv FENV_ACCESS
210is off, the floating-point environment will become undefined.
211.Sh EXAMPLES
212The following routine computes the square root function.
213It explicitly raises an invalid exception on appropriate inputs using
214.Fn feraiseexcept .
215It also defers inexact exceptions while it computes intermediate
216values, and then it allows an inexact exception to be raised only if
217the final answer is inexact.
218.Bd -literal -offset indent
219#pragma STDC FENV_ACCESS ON
220double sqrt(double n) {
221	double x = 1.0;
222	fenv_t env;
223
224	if (isnan(n) || n < 0.0) {
225		feraiseexcept(FE_INVALID);
226		return (NAN);
227	}
228	if (isinf(n) || n == 0.0)
229		return (n);
230	feholdexcept(&env);
231	while (fabs((x * x) - n) > DBL_EPSILON * 2 * x)
232		x = (x / 2) + (n / (2 * x));
233	if (x * x == n)
234		feclearexcept(FE_INEXACT);
235	feupdateenv(&env);
236	return (x);
237}
238.Ed
239.Sh SEE ALSO
240.Xr cc 1 ,
241.Xr feclearexcept 3 ,
242.Xr fedisableexcept 3 ,
243.Xr feenableexcept 3 ,
244.Xr fegetenv 3 ,
245.Xr fegetexcept 3 ,
246.Xr fegetexceptflag 3 ,
247.Xr fegetround 3 ,
248.Xr feholdexcept 3 ,
249.Xr feraiseexcept 3 ,
250.Xr fesetenv 3 ,
251.Xr fesetexceptflag 3 ,
252.Xr fesetround 3 ,
253.Xr fetestexcept 3 ,
254.Xr feupdateenv 3 ,
255.Xr fpgetprec 3 ,
256.Xr fpsetprec 3
257.Sh STANDARDS
258Except as noted below,
259.In fenv.h
260conforms to
261.St -isoC-99 .
262The
263.Fn feenableexcept ,
264.Fn fedisableexcept ,
265and
266.Fn fegetexcept
267routines are extensions.
268.Sh HISTORY
269The
270.In fenv.h
271header first appeared in
272.Fx 5.3 .
273It supersedes the non-standard routines defined in
274.In ieeefp.h
275and documented in
276.Xr fpgetround 3 .
277.Sh BUGS
278The
279.Dv FENV_ACCESS
280pragma is unimplemented in the system compiler.
281However, non-constant expressions generally produce the correct
282side-effects at low optimization levels.
283