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