• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

FloatingPoint.cc

Go to the documentation of this file.
00001 //
00002 // $Id: FloatingPoint.cpp,v 1.2 2008/07/14 23:33:53 lxmota Exp $
00003 //
00004 // $Log: FloatingPoint.cpp,v $
00005 // Revision 1.2  2008/07/14 23:33:53  lxmota
00006 // Updated to work on MacOS X (Darwin)
00007 //
00008 // Revision 1.1  2008/07/14 17:50:46  lxmota
00009 // Initial sources.
00010 //
00011 //
00012 
00013 //
00014 // 2001/10/02 22:45:15 by Jaroslaw Knap
00015 // Imported sources.
00016 //
00017 
00018 #include <fenv.h>
00019 
00020 #include "FloatingPoint.h"
00021 
00022 bool LCM::FloatingPoint::active_ = false;
00023 unsigned  LCM::FloatingPoint::oldMask_ = LCM::emptyMask_;
00024 
00025 //
00026 //
00027 //
00028 
00029 namespace LCM {
00030 
00031   FloatingPoint::FloatingPoint()
00032   {
00033 
00034     if (active_) return;
00035 
00036     oldMask_ = getCurrentMask();
00037     active_  = true;
00038     return;
00039 
00040   }
00041 
00042   FloatingPoint::~FloatingPoint()
00043   {
00044 
00045     if (!active_) return;
00046 
00047     setMask(oldMask_);
00048     active_ = false;
00049     return;
00050 
00051   }
00052 
00053 
00054 }
00055 
00056 
00057 //
00058 // all architectures with <fenv.h> available
00059 //
00060 
00061 //
00062 // fully ISO/IEC C99 compliant
00063 //
00064 
00065 #if defined(HAVE_FESETTRAPENABLE)
00066 
00067 // set traps
00068 
00069 namespace LCM {
00070 
00071   void FloatingPoint::trapInexact()
00072   {
00073 
00074     fesettrapenable(FE_INEXACT);
00075     return;
00076 
00077   }
00078 
00079   void FloatingPoint::trapDivbyzero()
00080   {
00081 
00082     fesettrapenable(FE_DIVBYZERO);
00083     return;
00084 
00085   }
00086 
00087   void FloatingPoint::trapUnderflow()
00088   {
00089 
00090     fesettrapenable(FE_UNDERFLOW);
00091     return;
00092 
00093   }
00094 
00095   void FloatingPoint::trapOverflow()
00096   {
00097 
00098     fesettrapenable(FE_OVERFLOW);
00099     return;
00100 
00101   }
00102 
00103   void FloatingPoint::trapInvalid()
00104   {
00105 
00106     fesettrapenable(FE_INVALID);
00107     return;
00108 
00109   }
00110 
00111   // get current trap mask
00112 
00113   unsigned FloatingPoint::getCurrentMask()
00114   {
00115 
00116     unsigned currentMask = emptyMask_;
00117     int currentTraps = fegettrapenable();
00118 
00119     if (currentTraps & FE_INEXACT)   currentMask |= inexactMask_;
00120     if (currentTraps & FE_DIVBYZERO) currentMask |= divbyzeroMask_;
00121     if (currentTraps & FE_UNDERFLOW) currentMask |= underflowMask_;
00122     if (currentTraps & FE_OVERFLOW)  currentMask |= overflowMask_;
00123     if (currentTraps & FE_INVALID)   currentMask |= invalidMask_;
00124 
00125     return currentMask;
00126 
00127   }
00128 
00129   // set mask
00130 
00131   void FloatingPoint::setMask(unsigned mask)
00132   {
00133 
00134     int currentTraps = 0;
00135 
00136     if (mask & inexactMask_)   currentTraps |= FE_INEXACT;
00137     if (mask & divbyzeroMask_) currentTraps |= FE_DIVBYZERO;
00138     if (mask & underflowMask_) currentTraps |= FE_UNDERFLOW;
00139     if (mask & overflowMask_)  currentTraps |= FE_OVERFLOW;
00140     if (mask & invalidMask_)   currentTraps |= FE_INVALID;
00141 
00142     fesettrapenable(currentTraps);
00143 
00144     return;
00145 
00146   }
00147 
00148 }
00149 
00150 #else
00151 
00152 #if defined(__linux__)
00153 
00154 //
00155 // subset of ISO/IEC C99; (linux)
00156 //
00157 
00158 void LCM::FloatingPoint::trapInexact()
00159 {
00160   feenableexcept( fegetexcept() | FE_INEXACT );
00161   return;
00162 }
00163 
00164 void LCM::FloatingPoint::trapDivbyzero()
00165 {
00166   feenableexcept( fegetexcept() | FE_DIVBYZERO );
00167   return;
00168 }
00169 
00170 void LCM::FloatingPoint::trapUnderflow()
00171 {
00172   feenableexcept( fegetexcept() | FE_UNDERFLOW );
00173   return;
00174 }
00175 
00176 void LCM::FloatingPoint::trapOverflow()
00177 {
00178   feenableexcept( fegetexcept() | FE_OVERFLOW );
00179   return;
00180 }
00181 
00182 void LCM::FloatingPoint::trapInvalid()
00183 {
00184   feenableexcept( fegetexcept() | FE_INVALID );
00185   return;
00186 }
00187 
00188 unsigned LCM::FloatingPoint::getCurrentMask()
00189 {
00190   return fegetexcept();
00191 }
00192 
00193 // set mask
00194 
00195 void LCM::FloatingPoint::setMask(unsigned mask)
00196 {
00197   feenableexcept( mask );
00198   return;
00199 }
00200 
00201 #else
00202 
00203 //
00204 // dummy interfaces
00205 //
00206 
00207 void LCM::FloatingPoint::trapInexact()
00208 {
00209 
00210   return;
00211 
00212 }
00213 
00214 void LCM::FloatingPoint::trapDivbyzero()
00215 {
00216 
00217   return;
00218 
00219 }
00220 
00221 void LCM::FloatingPoint::trapUnderflow()
00222 {
00223 
00224   return;
00225 
00226 }
00227 
00228 void LCM::FloatingPoint::trapOverflow()
00229 {
00230 
00231   return;
00232 
00233 }
00234 
00235 void LCM::FloatingPoint::trapInvalid()
00236 {
00237 
00238   return;
00239 
00240 }
00241 
00242 unsigned LCM::FloatingPoint::getCurrentMask()
00243 {
00244 
00245   return emptyMask_;
00246 
00247 }
00248 
00249 // set mask
00250 
00251 void LCM::FloatingPoint::setMask(unsigned mask)
00252 {
00253 
00254   return;
00255 
00256 }
00257 
00258 #endif // linux
00259 
00260 #endif // HAVE_FESETTRAPENABLE

Generated on Wed Mar 26 2014 18:36:38 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1