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