xref: /freebsd/lib/msun/man/fenv.3 (revision 9aff62dee28239f84b4aa4a3429cf26dbbf770cc)
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.Dd August 31, 2026
26.Dt FENV 3
27.Os
28.Sh NAME
29.Nm feclearexcept ,
30.Nm fegetexceptflag ,
31.Nm feraiseexcept ,
32.Nm fesetexceptflag ,
33.Nm fetestexcept ,
34.Nm fegetmode ,
35.Nm fesetmode ,
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 fegetmode "femode_t *modep"
63.Ft int
64.Fn fesetmode "const femode_t *modep"
65.Ft int
66.Fn fegetround void
67.Ft int
68.Fn fesetround "int round"
69.Ft int
70.Fn fegetenv "fenv_t *envp"
71.Ft int
72.Fn feholdexcept "fenv_t *envp"
73.Ft int
74.Fn fesetenv "const fenv_t *envp"
75.Ft int
76.Fn feupdateenv "const fenv_t *envp"
77.Ft int
78.Fn feenableexcept "int excepts"
79.Ft int
80.Fn fedisableexcept "int excepts"
81.Ft int
82.Fn fegetexcept void
83.Sh DESCRIPTION
84The
85.In fenv.h
86routines manipulate the floating-point environment,
87which includes the exception flags and rounding modes defined in
88.St -ieee754 .
89.Ss Exceptions
90Exception flags are set as side-effects of floating-point arithmetic
91operations and math library routines, and they remain set until
92explicitly cleared.
93The following macros expand to bit flags of type
94.Vt int
95representing the five standard floating-point exceptions.
96.Bl -tag -width ".Dv FE_DIVBYZERO"
97.It Dv FE_DIVBYZERO
98A divide-by-zero exception occurs when the
99.Em exact
100result of a computation is infinite (according to the limit definition).
101For example, dividing a finite non-zero number by zero or computing
102.Fn log 0
103raises a divide-by-zero exception.
104.It Dv FE_INEXACT
105An inexact exception is raised whenever there is a loss of accuracy
106due to rounding.
107.It Dv FE_INVALID
108Invalid operation exceptions occur when a program attempts to
109perform calculations for which there is no reasonable representable
110answer.
111For instance, subtraction of like-signed infinities, division of zero by zero,
112ordered comparison involving \*(Nas, and taking the real square root of a
113negative number are all invalid operations.
114.It Dv FE_OVERFLOW
115In contrast with divide-by-zero,
116an overflow exception occurs when an infinity is produced because
117the magnitude of the exact result is
118.Em finite
119but too large to fit in the destination type.
120For example, computing
121.Li DBL_MAX * 2
122raises an overflow exception.
123.It Dv FE_UNDERFLOW
124Underflow occurs when the result of a computation loses precision
125because it is too close to zero.
126The result is a subnormal number or zero.
127.El
128.Pp
129Additionally, the
130.Dv FE_ALL_EXCEPT
131macro expands to the bitwise OR of the above flags and any
132architecture-specific flags.
133Combinations of these flags are passed to the
134.Fn feclearexcept ,
135.Fn fegetexceptflag ,
136.Fn feraiseexcept ,
137.Fn fesetexceptflag ,
138and
139.Fn fetestexcept
140functions to clear, save, raise, restore, and examine the
141processor's floating-point exception flags, respectively.
142.Pp
143Exceptions may be
144.Em unmasked
145with
146.Fn feenableexcept
147and masked with
148.Fn fedisableexcept .
149Unmasked exceptions cause a trap when they are produced, and
150all exceptions are masked by default.
151The current mask can be tested with
152.Fn fegetexcept .
153.Ss Rounding Modes
154.St -ieee754
155specifies four rounding modes.
156These modes control the direction in which results are rounded
157from their exact values in order to fit them into binary
158floating-point variables.
159The four modes correspond with the following symbolic constants.
160.Bl -tag -width ".Dv FE_TOWARDZERO"
161.It Dv FE_TONEAREST
162Results are rounded to the closest representable value.
163If the exact result is exactly half way between two representable
164values, the value whose last binary digit is even (zero) is chosen.
165This is the default mode.
166.It Dv FE_DOWNWARD
167Results are rounded towards negative \*[If].
168.It Dv FE_UPWARD
169Results are rounded towards positive \*[If].
170.It Dv FE_TOWARDZERO
171Results are rounded towards zero.
172.El
173.Pp
174The
175.Fn fegetround
176and
177.Fn fesetround
178functions query and set the rounding mode.
179.Ss Control Modes
180The
181.Vt femode_t
182type represents the collection of dynamic floating-point control modes,
183including the rounding direction and, where supported, exception masks
184and other implementation-defined modes.
185The
186.Fn fegetmode
187and
188.Fn fesetmode
189functions save and restore all the implementation's dynamic
190floating-point control modes, respectively.
191Passing
192.Dv FE_DFL_MODE
193to
194.Fn fesetmode
195restores the default control modes as installed at program startup.
196.Pp
197The macro
198.Dv FE_DFL_MODE
199expands to a pointer to the constant variable of type
200.Vt femode_t
201that is initialized with the default control modes.
202.Ss Environment Control
203The
204.Fn fegetenv
205and
206.Fn fesetenv
207functions save and restore the floating-point environment,
208which includes exception flags, the current exception mask,
209the rounding mode, and possibly other implementation-specific
210state.
211The
212.Fn feholdexcept
213function behaves like
214.Fn fegetenv ,
215but with the additional effect of clearing the exception flags and
216installing a
217.Em non-stop
218mode.
219In non-stop mode, floating-point operations will set exception flags
220as usual, but no
221.Dv SIGFPE
222signals will be generated as a result.
223Non-stop mode is the default, but it may be altered by
224.Fn feenableexcept
225and
226.Fn fedisableexcept .
227The
228.Fn feupdateenv
229function restores a saved environment similarly to
230.Fn fesetenv ,
231but it also re-raises any floating-point exceptions from the old
232environment.
233.Pp
234The macro
235.Dv FE_DFL_ENV
236expands to a pointer to the default environment.
237.Sh EXAMPLES
238The following routine computes the square root function.
239It explicitly raises an invalid exception on appropriate inputs using
240.Fn feraiseexcept .
241It also defers inexact exceptions while it computes intermediate
242values, and then it allows an inexact exception to be raised only if
243the final answer is inexact.
244.Bd -literal -offset indent
245#pragma STDC FENV_ACCESS ON
246double sqrt(double n) {
247	double x = 1.0;
248	fenv_t env;
249
250	if (isnan(n) || n < 0.0) {
251		feraiseexcept(FE_INVALID);
252		return (NAN);
253	}
254	if (isinf(n) || n == 0.0)
255		return (n);
256	feholdexcept(&env);
257	while (fabs((x * x) - n) > DBL_EPSILON * 2 * x)
258		x = (x / 2) + (n / (2 * x));
259	if (x * x == n)
260		feclearexcept(FE_INEXACT);
261	feupdateenv(&env);
262	return (x);
263}
264.Ed
265.Sh SEE ALSO
266.Xr cc 1 ,
267.Xr feclearexcept 3 ,
268.Xr fedisableexcept 3 ,
269.Xr feenableexcept 3 ,
270.Xr fegetenv 3 ,
271.Xr fegetexcept 3 ,
272.Xr fegetexceptflag 3 ,
273.Xr fegetmode 3 ,
274.Xr fegetround 3 ,
275.Xr feholdexcept 3 ,
276.Xr feraiseexcept 3 ,
277.Xr fesetenv 3 ,
278.Xr fesetexceptflag 3 ,
279.Xr fesetmode 3 ,
280.Xr fesetround 3 ,
281.Xr fetestexcept 3 ,
282.Xr feupdateenv 3 ,
283.Xr fpgetprec 3 ,
284.Xr fpsetprec 3
285.Sh STANDARDS
286Except as noted below,
287.In fenv.h
288conforms to
289.St -isoC-99 .
290The
291.Vt femode_t
292type, the
293.Dv FE_DFL_MODE
294macro, and the
295.Fn fegetmode
296and
297.Fn fesetmode
298functions conform to
299.St -isoC-2023 .
300The
301.Fn feenableexcept ,
302.Fn fedisableexcept ,
303and
304.Fn fegetexcept
305routines are extensions.
306.Sh HISTORY
307The
308.In fenv.h
309header first appeared in
310.Fx 5.3 .
311It supersedes the non-standard routines defined in
312.In ieeefp.h
313and documented in
314.Xr fpgetround 3 .
315The
316.Fn fegetmode
317and
318.Fn fesetmode
319functions first appeared in
320.Fx 16.0 .
321.Sh CAVEATS
322The FENV_ACCESS pragma can be enabled with
323.Dl "#pragma STDC FENV_ACCESS ON"
324and disabled with the
325.Dl "#pragma STDC FENV_ACCESS OFF"
326directive.
327This lexically-scoped annotation tells the compiler that the program
328may access the floating-point environment, so optimizations that would
329violate strict IEEE-754 semantics are disabled.
330If execution reaches a block of code for which
331.Dv FENV_ACCESS
332is off, the floating-point environment will become undefined.
333.Sh BUGS
334The
335.Dv FENV_ACCESS
336pragma is unimplemented in the system compiler.
337However, non-constant expressions generally produce the correct
338side-effects at low optimization levels.
339