...
Operating System | Handling FP errors | |
---|---|---|
Linux | C99 FP functions - These functions are declared in fenv.h [2] | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="731e193c041400df-760e3d86-46764229-8f38a642-1150c998d37b16c544696ad3"><ac:plain-text-body><![CDATA[ | Windows | Structured Exception Handling - user defined handler _fpieee_flt [3] |
...
Code Block | ||
---|---|---|
| ||
fpOper_noErrorChecking() { /* ... */ double a = 1e-40, b, c = 0.1; float x = 0, y; //* inexact and underflows */ y = a; //* divide by zero operation */ b = y / x; //* inexact (loss of precision) */ c = sin(30) * a; /* ... */ } |
Compliant Solution
Here is an example that demonstrates how to handle FP operations using the FP functions as standardized in C99This compliant solution uses C99 standard functions to handle floating point errors.
Code Block | ||
---|---|---|
| ||
#include <fenv.h> fpOper_fenv() { double a = 1e-40, b, c = 0.1; float x = 0, y; int fpeRaised; /* ... */ feclearexcept(FE_ALL_EXCEPT); //* Store a into y is inexact and underflows: */ y = a; fpeRaised = fetestexcept(FE_ALL_EXCEPT); //* fpeRaised has FE_INEXACT and FE_UNDERFLOW */ feclearexcept(FE_ALL_EXCEPT); //* divide by zero operation */ b = y / x; fpeRaised = fetestexcept(FE_ALL_EXCEPT); //* fpeRaised has FE_DIVBYZERO */ feclearexcept(FE_ALL_EXCEPT); c = sin(30) * a; fpeRaised = fetestexcept(FE_ALL_EXCEPT); //* fpeRaised has FE_INEXACT */ feclearexcept(FE_ALL_EXCEPT); /* ..... */ } |
Implementation-Specific Details
Compliant Solution (Windows)
MS Visual Studio 2008 and earlier does not support the C99 functions to handle floating point errors. Windows Windows OS nor the libraries with MS Visual studio support C99 functions, instead Structured Exception Handling is used to handle for FP operation. Windows also provides an alternative method to get the FP floating point exception code - using _statusfp
/()
, _statusfp2()
, and /or _clearfp()
.
Code Block | ||
---|---|---|
| ||
fpOper_usingStatus() { /* .... */ double a = 1e-40, b, c; float x = 0, y; unsigned int rv = _clearfp() ; //* Store into y is inexact and underflows: */ y = a; rv = _clearfp() ; //* rv has _SW_INEXACT and _SW_UNDERFLOW */ //* zero-divide */ b = y / x; rv = _clearfp() ; //* rv has _SW_ZERODIVIDE */ //* inexact */ c = sin(30) * a; rv = _clearfp() ; //* rv has _SW_INEXACT */ /* .... */ } |
Compliant Solution (Windows)
MS Visual Studio 2008 also uses structured exception handling (SEH) is used to handle for floating point operation. Using the SEH allows the programmer to change the results of the FP floating point operation that caused the error condition. Using SEH also provides more information about the error condition.
Code Block | ||
---|---|---|
| ||
fp_usingSEH() { /* ... */ double a = 1e-40, b, c = 0.1; float x = 0, y; unsigned int rv ; unmask_fp(); _try { // /* Store into y is inexact and underflows: */ y = a; // /* divide by zero operation */ b = y / x; // /* inexact */ c = sin(30) * a; } _except (_fpieee_flt (GetExceptionCode(), GetExceptionInformation(), fpieee_handler)) { printf ("fpieee_handler: EXCEPTION_EXECUTE_HANDLER"); } /* ... */ } void unmask_fpsr(void) { unsigned int u; unsigned int control_word; _controlfp_s(&control_word, 0, 0); u = control_word & ~(_EM_INVALID \| _EM_DENORMAL \| _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT); _controlfp_s( &control_word, u, _MCW_EM); return ; } int fpieee_handler (_FPIEEE_RECORD *ieee) { //* ... */ switch(ieee->RoundingMode) { case _FpRoundNearest: // /* .... */ break; /* Other RMs include _FpRoundMinusInfinity, _FpRoundPlusInfinity, _FpRoundChopped */ // /* .... */ } switch(ieee->Precision) { case _FpPrecision24: // /* .... */ break; /* Other Ps include _FpPrecision53*/ // /* .... */ } switch(ieee->Operation) { case _FpCodeAdd: //* ... */ break; /* Other Ops include _FpCodeSubtract, _FpCodeMultiply, _FpCodeDivide, _FpCodeSquareRoot, _FpCodeCompare, _FpCodeConvert, _FpCodeConvertTrunc */ // /* .... */ } //* process the bitmap ieee->Cause */ //* process the bitmap ieee->Enable */ //* process the bitmap ieee->Status */ //* process the Operand ieee->Operand1, evaluate format and Value */ //* process the Operand ieee->Operand2, evaluate format and Value */ //* process the Result ieee->Result, evaluate format and Value */ //* the result should be set according to the operation specified in ieee->Cause and the result format as specified in ieee->Result */ //* the Result set is based on the */ //* ... */ } |
Risk Assessment
The Floating point exceptions if they go undetected will cause one or more of these conditions - security vulnerability, lower program efficiency and generate inaccurate results. Most processors stall for significant duration (sometimes upto a second or even more on 32bit desktop processors) when an operation incur a NaN.
...