xref: /freebsd/lib/msun/man/fenv.3 (revision 74bf4e164ba5851606a27d4feff27717452583e5)
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 May 8, 2004
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.Nd floating-point environment control
43.Sh LIBRARY
44.Lb libm
45.Sh SYNOPSIS
46.In fenv.h
47.Fd "#pragma STDC FENV_ACCESS ON"
48.Ft int
49.Fn feclearexcept "int excepts"
50.Ft int
51.Fn fegetexceptflag "fexcept_t *flagp" "int excepts"
52.Ft int
53.Fn feraiseexcept "int excepts"
54.Ft int
55.Fn fesetexceptflag "const fexcept_t *flagp" "int excepts"
56.Ft int
57.Fn fetestexcept "int excepts"
58.Ft int
59.Fn fegetround "void"
60.Ft int
61.Fn fesetround "int round"
62.Ft int
63.Fn fegetenv "fenv_t *envp"
64.Ft int
65.Fn feholdexcept "fenv_t *envp"
66.Ft int
67.Fn fesetenv "const fenv_t *envp"
68.Ft int
69.Fn feupdateenv "const fenv_t *envp"
70.Sh DESCRIPTION
71The fenv routines manipulate the floating-point environment,
72which includes the exception flags and rounding modes defined in
73.St -ieee754 .
74.Ss Exceptions
75Exception flags are set as side-effects of floating-point arithmetic
76operations and math library routines, and they remain set until
77explicitly cleared.
78The following macros expand to bit flags of type
79.Vt int
80representing the five standard floating-point exceptions.
81.Bl -tag -width ".Dv FE_DIVBYZERO"
82.It Dv "FE_DIVBYZERO"
83A divide-by-zero exception occurs when the program attempts to
84divide a finite non-zero number by zero.
85.It Dv "FE_INEXACT"
86An inexact exception is raised whenever there is a loss of precision
87due to rounding.
88.It Dv "FE_INVALID"
89Invalid operation exceptions occur when a program attempts to
90perform calculations for which there is no reasonable representable
91answer.
92For instance, subtraction of infinities, division of zero by zero,
93ordered comparison involving
94.Na
95s, and taking the square root of a
96negative number are all invalid operations.
97.It Dv "FE_OVERFLOW"
98An overflow exception occurs when the magnitude of the result of a
99computation is too large to fit in the destination type.
100.It Dv "FE_UNDERFLOW"
101Underflow occurs when the result of a computation is too close to zero
102to be represented as a non-zero value in the destination type.
103.El
104.Pp
105Additionally, the
106.Dv FE_ALL_EXCEPT
107macro expands to the bitwise OR of the above flags and any
108architecture-specific flags.
109Combinations of these flags are passed to the
110.Fn feclearexcept ,
111.Fn fegetexceptflag ,
112.Fn feraiseexcept ,
113.Fn fesetexceptflag ,
114and
115.Fn fetestexcept
116functions to clear, save, raise, restore, and examine the
117processor's floating-point exception flags, respectively.
118.Ss Rounding Modes
119.St -ieee754
120specifies four rounding modes.
121These modes control the direction in which results are rounded
122from their exact values in order to fit them into binary
123floating-point variables.
124The four modes correspond with the following symbolic constants.
125.Bl -tag -width ".Dv FE_TOWARDZERO"
126.It Dv "FE_TONEAREST"
127Results are rounded to the closest representable value.
128If the exact result is exactly half way between two representable
129values, the value whose last binary digit is even (zero) is chosen.
130This is the default mode.
131.It Dv "FE_DOWNWARD"
132Results are rounded towards negative \*[If].
133.It Dv "FE_UPWARD"
134Results are rounded towards positive \*[If].
135.It Dv "FE_TOWARDZERO"
136Results are rounded towards zero.
137.El
138.Pp
139The
140.Fn fegetround
141and
142.Fn fesetround
143functions query and set the rounding mode.
144.Ss Environment Control
145The
146.Fn fegetenv
147and
148.Fn fesetenv
149functions save and restore the floating-point environment,
150which includes exception flags, the current exception mask,
151the rounding mode, and possibly other implementation-specific
152state.
153The
154.Fn feholdexcept
155function behaves like
156.Fn fegetenv ,
157but with the additional effect of clearing the exception flags and
158installing a
159.Em non-stop
160mode.
161In non-stop mode, floating-point operations will set exception flags
162as usual, but no
163.Dv SIGFPE
164signals will be generated as a result.
165Non-stop mode is the default, but it may be altered by
166non-standard mechanisms.
167.\" XXX Mention fe[gs]etmask() here after the interface is finalized
168.\" XXX and ready to be officially documented.
169The
170.Fn feupdateenv
171function restores a saved environment similarly to
172.Fn fesetenv ,
173but it also re-raises any floating-point exceptions from the old
174environment.
175.Pp
176The macro
177.Dv FE_DFL_ENV
178expands to a pointer to the default environment.
179.Sh CAVEATS
180The FENV_ACCESS pragma can be enabled with
181.Dl "#pragma STDC FENV_ACCESS ON"
182and disabled with the
183.Dl "#pragma STDC FENV_ACCESS OFF"
184directive.
185This lexically-scoped annotation tells the compiler that the program
186may access the floating-point environment, so optimizations that would
187violate strict IEEE-754 semantics are disabled.
188If execution reaches a block of code for which
189.Dv FENV_ACCESS
190is off, the floating-point environment will become undefined.
191.Sh EXAMPLES
192The following routine computes the square root function.
193It explicitly raises an invalid exception on appropriate inputs using
194.Fn feraiseexcept .
195It also defers inexact exceptions while it computes intermediate
196values, and then it allows an inexact exception to be raised only if
197the final answer is inexact.
198.Bd -literal -offset indent
199#pragma STDC FENV_ACCESS ON
200double sqrt(double n) {
201	double x = 1.0;
202	fenv_t env;
203
204	if (isnan(n) || n < 0.0) {
205		feraiseexcept(FE_INVALID);
206		return (NAN);
207	}
208	if (isinf(n) || n == 0.0)
209		return (n);
210	feholdexcept(&env);
211	while (fabs((x * x) - n) > DBL_EPSILON * 2 * x)
212		x = (x / 2) + (n / (2 * x));
213	if (x * x == n)
214		feclearexcept(FE_INEXACT);
215	feupdateenv(&env);
216	return (x);
217}
218.Ed
219.Sh SEE ALSO
220.Xr cc 1 ,
221.Xr feclearexcept 3 ,
222.Xr fegetenv 3 ,
223.Xr fegetexceptflag 3 ,
224.Xr fegetround 3 ,
225.Xr feholdexcept 3 ,
226.Xr feraiseexcept 3 ,
227.Xr fesetenv 3 ,
228.Xr fesetexceptflag 3 ,
229.Xr fesetround 3 ,
230.Xr fetestexcept 3 ,
231.Xr feupdateenv 3 ,
232.Xr fpgetmask 3 ,
233.Xr fpgetprec 3 ,
234.Xr fpgetsticky 3 ,
235.Xr fpgetround 3 ,
236.Xr fpresetsticky 3 ,
237.Xr fpsetmask 3 ,
238.Xr fpsetprec 3 ,
239.Xr fpsetround 3
240.Sh STANDARDS
241Except as noted below,
242.In fenv.h
243conforms to
244.St -isoC-99 .
245.Sh HISTORY
246The
247.In fenv.h
248header first appeared in
249.Fx 5.3 .
250It supersedes the non-standard routines defined in
251.In ieeefp.h
252and documented in
253.Xr fpgetround 3 .
254.Sh BUGS
255The
256.Dv FENV_ACCESS
257pragma is unimplemented in the system compiler.
258However, non-constant expressions generally produce the correct
259side-effects at low optimization levels.
260.Pp
261On the Alpha platform,
262.Xr cc 1
263must be passed the
264.Fl mieee-with-inexact mfp-rounding-mode=d
265options in order to generate code that has the standard
266side-effects and uses the specified rounding modes.
267