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