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