107235cc8SDavid Schultz.\" Copyright (c) 2004 David Schultz <das@FreeBSD.org> 207235cc8SDavid Schultz.\" All rights reserved. 307235cc8SDavid Schultz.\" 407235cc8SDavid Schultz.\" Redistribution and use in source and binary forms, with or without 507235cc8SDavid Schultz.\" modification, are permitted provided that the following conditions 607235cc8SDavid Schultz.\" are met: 707235cc8SDavid Schultz.\" 1. Redistributions of source code must retain the above copyright 807235cc8SDavid Schultz.\" notice, this list of conditions and the following disclaimer. 907235cc8SDavid Schultz.\" 2. Redistributions in binary form must reproduce the above copyright 1007235cc8SDavid Schultz.\" notice, this list of conditions and the following disclaimer in the 1107235cc8SDavid Schultz.\" documentation and/or other materials provided with the distribution. 1207235cc8SDavid Schultz.\" 1307235cc8SDavid Schultz.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1407235cc8SDavid Schultz.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1507235cc8SDavid Schultz.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1607235cc8SDavid Schultz.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1707235cc8SDavid Schultz.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1807235cc8SDavid Schultz.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1907235cc8SDavid Schultz.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2007235cc8SDavid Schultz.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2107235cc8SDavid Schultz.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2207235cc8SDavid Schultz.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2307235cc8SDavid Schultz.\" SUCH DAMAGE. 2407235cc8SDavid Schultz.\" 2510b01832SDavid Schultz.Dd March 16, 2005 2607235cc8SDavid Schultz.Dt FENV 3 2707235cc8SDavid Schultz.Os 2807235cc8SDavid Schultz.Sh NAME 2907235cc8SDavid Schultz.Nm feclearexcept , 3007235cc8SDavid Schultz.Nm fegetexceptflag , 3107235cc8SDavid Schultz.Nm feraiseexcept , 3207235cc8SDavid Schultz.Nm fesetexceptflag , 3307235cc8SDavid Schultz.Nm fetestexcept , 3407235cc8SDavid Schultz.Nm fegetround , 3507235cc8SDavid Schultz.Nm fesetround , 3607235cc8SDavid Schultz.Nm fegetenv , 3707235cc8SDavid Schultz.Nm feholdexcept , 3807235cc8SDavid Schultz.Nm fesetenv , 3910b01832SDavid Schultz.Nm feupdateenv , 4010b01832SDavid Schultz.Nm feenableexcept , 4110b01832SDavid Schultz.Nm fedisableexcept , 4210b01832SDavid Schultz.Nm fegetexcept 4307235cc8SDavid Schultz.Nd floating-point environment control 4407235cc8SDavid Schultz.Sh LIBRARY 4507235cc8SDavid Schultz.Lb libm 4607235cc8SDavid Schultz.Sh SYNOPSIS 4707235cc8SDavid Schultz.In fenv.h 4807235cc8SDavid Schultz.Fd "#pragma STDC FENV_ACCESS ON" 4907235cc8SDavid Schultz.Ft int 5007235cc8SDavid Schultz.Fn feclearexcept "int excepts" 5107235cc8SDavid Schultz.Ft int 5207235cc8SDavid Schultz.Fn fegetexceptflag "fexcept_t *flagp" "int excepts" 5307235cc8SDavid Schultz.Ft int 5407235cc8SDavid Schultz.Fn feraiseexcept "int excepts" 5507235cc8SDavid Schultz.Ft int 5607235cc8SDavid Schultz.Fn fesetexceptflag "const fexcept_t *flagp" "int excepts" 5707235cc8SDavid Schultz.Ft int 5807235cc8SDavid Schultz.Fn fetestexcept "int excepts" 5907235cc8SDavid Schultz.Ft int 60e880667bSRuslan Ermilov.Fn fegetround void 6107235cc8SDavid Schultz.Ft int 6207235cc8SDavid Schultz.Fn fesetround "int round" 6307235cc8SDavid Schultz.Ft int 6407235cc8SDavid Schultz.Fn fegetenv "fenv_t *envp" 6507235cc8SDavid Schultz.Ft int 6607235cc8SDavid Schultz.Fn feholdexcept "fenv_t *envp" 6707235cc8SDavid Schultz.Ft int 6807235cc8SDavid Schultz.Fn fesetenv "const fenv_t *envp" 6907235cc8SDavid Schultz.Ft int 7007235cc8SDavid Schultz.Fn feupdateenv "const fenv_t *envp" 7110b01832SDavid Schultz.Ft int 7210b01832SDavid Schultz.Fn feenableexcept "int excepts" 7310b01832SDavid Schultz.Ft int 7410b01832SDavid Schultz.Fn fedisableexcept "int excepts" 7510b01832SDavid Schultz.Ft int 76f789cb82SRuslan Ermilov.Fn fegetexcept void 7707235cc8SDavid Schultz.Sh DESCRIPTION 78e880667bSRuslan ErmilovThe 79e880667bSRuslan Ermilov.In fenv.h 80e880667bSRuslan Ermilovroutines manipulate the floating-point environment, 8107235cc8SDavid Schultzwhich includes the exception flags and rounding modes defined in 8207235cc8SDavid Schultz.St -ieee754 . 8307235cc8SDavid Schultz.Ss Exceptions 8407235cc8SDavid SchultzException flags are set as side-effects of floating-point arithmetic 8507235cc8SDavid Schultzoperations and math library routines, and they remain set until 8607235cc8SDavid Schultzexplicitly cleared. 8707235cc8SDavid SchultzThe following macros expand to bit flags of type 8807235cc8SDavid Schultz.Vt int 8907235cc8SDavid Schultzrepresenting the five standard floating-point exceptions. 9007235cc8SDavid Schultz.Bl -tag -width ".Dv FE_DIVBYZERO" 91e880667bSRuslan Ermilov.It Dv FE_DIVBYZERO 92*1f52bcddSDavid SchultzA divide-by-zero exception occurs when the 93*1f52bcddSDavid Schultz.Em exact 94*1f52bcddSDavid Schultzresult of a computation is infinite (according to the limit definition). 95*1f52bcddSDavid SchultzFor example, dividing a finite non-zero number by zero or computing 96*1f52bcddSDavid Schultz.Fn log 0 97*1f52bcddSDavid Schultzraises a divide-by-zero exception. 98e880667bSRuslan Ermilov.It Dv FE_INEXACT 99*1f52bcddSDavid SchultzAn inexact exception is raised whenever there is a loss of accuracy 10007235cc8SDavid Schultzdue to rounding. 101e880667bSRuslan Ermilov.It Dv FE_INVALID 10207235cc8SDavid SchultzInvalid operation exceptions occur when a program attempts to 10307235cc8SDavid Schultzperform calculations for which there is no reasonable representable 10407235cc8SDavid Schultzanswer. 105*1f52bcddSDavid SchultzFor instance, subtraction of like-signed infinities, division of zero by zero, 106*1f52bcddSDavid Schultzordered comparison involving \*(Nas, and taking the real square root of a 10707235cc8SDavid Schultznegative number are all invalid operations. 108e880667bSRuslan Ermilov.It Dv FE_OVERFLOW 109*1f52bcddSDavid SchultzIn contrast with divide-by-zero, 110*1f52bcddSDavid Schultzan overflow exception occurs when an infinity is produced because 111*1f52bcddSDavid Schultzthe magnitude of the exact result is 112*1f52bcddSDavid Schultz.Em finite 113*1f52bcddSDavid Schultzbut too large to fit in the destination type. 114*1f52bcddSDavid SchultzFor example, computing 115*1f52bcddSDavid Schultz.Li DBL_MAX * 2 116*1f52bcddSDavid Schultzraises an overflow exception. 117e880667bSRuslan Ermilov.It Dv FE_UNDERFLOW 118*1f52bcddSDavid SchultzUnderflow occurs when the result of a computation loses precision 119*1f52bcddSDavid Schultzbecause it is too close to zero. 120*1f52bcddSDavid SchultzThe result is a subnormal number or zero. 12107235cc8SDavid Schultz.El 12207235cc8SDavid Schultz.Pp 12307235cc8SDavid SchultzAdditionally, the 12407235cc8SDavid Schultz.Dv FE_ALL_EXCEPT 12507235cc8SDavid Schultzmacro expands to the bitwise OR of the above flags and any 12607235cc8SDavid Schultzarchitecture-specific flags. 12707235cc8SDavid SchultzCombinations of these flags are passed to the 12807235cc8SDavid Schultz.Fn feclearexcept , 12907235cc8SDavid Schultz.Fn fegetexceptflag , 13007235cc8SDavid Schultz.Fn feraiseexcept , 13107235cc8SDavid Schultz.Fn fesetexceptflag , 13207235cc8SDavid Schultzand 13307235cc8SDavid Schultz.Fn fetestexcept 13407235cc8SDavid Schultzfunctions to clear, save, raise, restore, and examine the 13507235cc8SDavid Schultzprocessor's floating-point exception flags, respectively. 13610b01832SDavid Schultz.Pp 13710b01832SDavid SchultzExceptions may be 13810b01832SDavid Schultz.Em unmasked 13910b01832SDavid Schultzwith 14010b01832SDavid Schultz.Fn feenableexcept 14110b01832SDavid Schultzand masked with 14210b01832SDavid Schultz.Fn fedisableexcept . 14310b01832SDavid SchultzUnmasked exceptions cause a trap when they are produced, and 14410b01832SDavid Schultzall exceptions are masked by default. 14510b01832SDavid SchultzThe current mask can be tested with 14610b01832SDavid Schultz.Fn fegetexcept . 14707235cc8SDavid Schultz.Ss Rounding Modes 14807235cc8SDavid Schultz.St -ieee754 14907235cc8SDavid Schultzspecifies four rounding modes. 15007235cc8SDavid SchultzThese modes control the direction in which results are rounded 15107235cc8SDavid Schultzfrom their exact values in order to fit them into binary 15207235cc8SDavid Schultzfloating-point variables. 15307235cc8SDavid SchultzThe four modes correspond with the following symbolic constants. 15407235cc8SDavid Schultz.Bl -tag -width ".Dv FE_TOWARDZERO" 155e880667bSRuslan Ermilov.It Dv FE_TONEAREST 15607235cc8SDavid SchultzResults are rounded to the closest representable value. 15707235cc8SDavid SchultzIf the exact result is exactly half way between two representable 15807235cc8SDavid Schultzvalues, the value whose last binary digit is even (zero) is chosen. 15907235cc8SDavid SchultzThis is the default mode. 160e880667bSRuslan Ermilov.It Dv FE_DOWNWARD 16107235cc8SDavid SchultzResults are rounded towards negative \*[If]. 162e880667bSRuslan Ermilov.It Dv FE_UPWARD 16307235cc8SDavid SchultzResults are rounded towards positive \*[If]. 164e880667bSRuslan Ermilov.It Dv FE_TOWARDZERO 16507235cc8SDavid SchultzResults are rounded towards zero. 16607235cc8SDavid Schultz.El 16707235cc8SDavid Schultz.Pp 16807235cc8SDavid SchultzThe 16907235cc8SDavid Schultz.Fn fegetround 17007235cc8SDavid Schultzand 17107235cc8SDavid Schultz.Fn fesetround 17207235cc8SDavid Schultzfunctions query and set the rounding mode. 17307235cc8SDavid Schultz.Ss Environment Control 17407235cc8SDavid SchultzThe 17507235cc8SDavid Schultz.Fn fegetenv 17607235cc8SDavid Schultzand 17707235cc8SDavid Schultz.Fn fesetenv 17807235cc8SDavid Schultzfunctions save and restore the floating-point environment, 17907235cc8SDavid Schultzwhich includes exception flags, the current exception mask, 18007235cc8SDavid Schultzthe rounding mode, and possibly other implementation-specific 18107235cc8SDavid Schultzstate. 18207235cc8SDavid SchultzThe 18307235cc8SDavid Schultz.Fn feholdexcept 18407235cc8SDavid Schultzfunction behaves like 18507235cc8SDavid Schultz.Fn fegetenv , 18607235cc8SDavid Schultzbut with the additional effect of clearing the exception flags and 18707235cc8SDavid Schultzinstalling a 18807235cc8SDavid Schultz.Em non-stop 18907235cc8SDavid Schultzmode. 19007235cc8SDavid SchultzIn non-stop mode, floating-point operations will set exception flags 19107235cc8SDavid Schultzas usual, but no 19207235cc8SDavid Schultz.Dv SIGFPE 19307235cc8SDavid Schultzsignals will be generated as a result. 19407235cc8SDavid SchultzNon-stop mode is the default, but it may be altered by 195*1f52bcddSDavid Schultz.Fn feenableexcept 196*1f52bcddSDavid Schultzand 197*1f52bcddSDavid Schultz.Fn fedisableexcept . 19807235cc8SDavid SchultzThe 19907235cc8SDavid Schultz.Fn feupdateenv 20007235cc8SDavid Schultzfunction restores a saved environment similarly to 20107235cc8SDavid Schultz.Fn fesetenv , 20207235cc8SDavid Schultzbut it also re-raises any floating-point exceptions from the old 20307235cc8SDavid Schultzenvironment. 20407235cc8SDavid Schultz.Pp 20507235cc8SDavid SchultzThe macro 20607235cc8SDavid Schultz.Dv FE_DFL_ENV 20707235cc8SDavid Schultzexpands to a pointer to the default environment. 20807235cc8SDavid Schultz.Sh EXAMPLES 20907235cc8SDavid SchultzThe following routine computes the square root function. 21007235cc8SDavid SchultzIt explicitly raises an invalid exception on appropriate inputs using 21107235cc8SDavid Schultz.Fn feraiseexcept . 21207235cc8SDavid SchultzIt also defers inexact exceptions while it computes intermediate 21307235cc8SDavid Schultzvalues, and then it allows an inexact exception to be raised only if 21407235cc8SDavid Schultzthe final answer is inexact. 21507235cc8SDavid Schultz.Bd -literal -offset indent 21607235cc8SDavid Schultz#pragma STDC FENV_ACCESS ON 21707235cc8SDavid Schultzdouble sqrt(double n) { 21807235cc8SDavid Schultz double x = 1.0; 21907235cc8SDavid Schultz fenv_t env; 22007235cc8SDavid Schultz 22107235cc8SDavid Schultz if (isnan(n) || n < 0.0) { 22207235cc8SDavid Schultz feraiseexcept(FE_INVALID); 22307235cc8SDavid Schultz return (NAN); 22407235cc8SDavid Schultz } 22507235cc8SDavid Schultz if (isinf(n) || n == 0.0) 22607235cc8SDavid Schultz return (n); 22707235cc8SDavid Schultz feholdexcept(&env); 22807235cc8SDavid Schultz while (fabs((x * x) - n) > DBL_EPSILON * 2 * x) 22907235cc8SDavid Schultz x = (x / 2) + (n / (2 * x)); 23007235cc8SDavid Schultz if (x * x == n) 23107235cc8SDavid Schultz feclearexcept(FE_INEXACT); 23207235cc8SDavid Schultz feupdateenv(&env); 23307235cc8SDavid Schultz return (x); 23407235cc8SDavid Schultz} 23507235cc8SDavid Schultz.Ed 23607235cc8SDavid Schultz.Sh SEE ALSO 23707235cc8SDavid Schultz.Xr cc 1 , 23807235cc8SDavid Schultz.Xr feclearexcept 3 , 23910b01832SDavid Schultz.Xr fedisableexcept 3 , 24010b01832SDavid Schultz.Xr feenableexcept 3 , 24107235cc8SDavid Schultz.Xr fegetenv 3 , 24210b01832SDavid Schultz.Xr fegetexcept 3 , 24307235cc8SDavid Schultz.Xr fegetexceptflag 3 , 24407235cc8SDavid Schultz.Xr fegetround 3 , 24507235cc8SDavid Schultz.Xr feholdexcept 3 , 24607235cc8SDavid Schultz.Xr feraiseexcept 3 , 24707235cc8SDavid Schultz.Xr fesetenv 3 , 24807235cc8SDavid Schultz.Xr fesetexceptflag 3 , 24907235cc8SDavid Schultz.Xr fesetround 3 , 25007235cc8SDavid Schultz.Xr fetestexcept 3 , 25107235cc8SDavid Schultz.Xr feupdateenv 3 , 25207235cc8SDavid Schultz.Xr fpgetprec 3 , 25310b01832SDavid Schultz.Xr fpsetprec 3 25407235cc8SDavid Schultz.Sh STANDARDS 25507235cc8SDavid SchultzExcept as noted below, 25607235cc8SDavid Schultz.In fenv.h 25707235cc8SDavid Schultzconforms to 25807235cc8SDavid Schultz.St -isoC-99 . 25910b01832SDavid SchultzThe 26010b01832SDavid Schultz.Fn feenableexcept , 26110b01832SDavid Schultz.Fn fedisableexcept , 26210b01832SDavid Schultzand 26310b01832SDavid Schultz.Fn fegetexcept 26410b01832SDavid Schultzroutines are extensions. 26507235cc8SDavid Schultz.Sh HISTORY 26607235cc8SDavid SchultzThe 26707235cc8SDavid Schultz.In fenv.h 26807235cc8SDavid Schultzheader first appeared in 26907235cc8SDavid Schultz.Fx 5.3 . 27007235cc8SDavid SchultzIt supersedes the non-standard routines defined in 27107235cc8SDavid Schultz.In ieeefp.h 27207235cc8SDavid Schultzand documented in 27307235cc8SDavid Schultz.Xr fpgetround 3 . 2740afc94c1SUlrich Spörlein.Sh CAVEATS 2750afc94c1SUlrich SpörleinThe FENV_ACCESS pragma can be enabled with 2760afc94c1SUlrich Spörlein.Dl "#pragma STDC FENV_ACCESS ON" 2770afc94c1SUlrich Spörleinand disabled with the 2780afc94c1SUlrich Spörlein.Dl "#pragma STDC FENV_ACCESS OFF" 2790afc94c1SUlrich Spörleindirective. 2800afc94c1SUlrich SpörleinThis lexically-scoped annotation tells the compiler that the program 2810afc94c1SUlrich Spörleinmay access the floating-point environment, so optimizations that would 2820afc94c1SUlrich Spörleinviolate strict IEEE-754 semantics are disabled. 2830afc94c1SUlrich SpörleinIf execution reaches a block of code for which 2840afc94c1SUlrich Spörlein.Dv FENV_ACCESS 2850afc94c1SUlrich Spörleinis off, the floating-point environment will become undefined. 28607235cc8SDavid Schultz.Sh BUGS 28707235cc8SDavid SchultzThe 28807235cc8SDavid Schultz.Dv FENV_ACCESS 28907235cc8SDavid Schultzpragma is unimplemented in the system compiler. 29007235cc8SDavid SchultzHowever, non-constant expressions generally produce the correct 29107235cc8SDavid Schultzside-effects at low optimization levels. 292