synaps/arithm/epsilon.h

00001 /********************************************************************
00002  *   This file is part of the source code of the SYNAPS library.
00003  *   Author(s): J.P. Pavone, GALAAD, INRIA
00004  *   $Id: epsilon.H,v 1.1 2005/07/11 09:15:23 mourrain Exp $
00005  ********************************************************************/
00006 #ifndef SYNAPS_NUMERICS_EPSILON_HPP
00007 #define SYNAPS_NUMERICS_EPSILON_HPP
00008 #include <synaps/init.h>
00009 #include <synaps/arithm/rounding.h>
00010 //--------------------------------------------------------------------
00011 __BEGIN_NAMESPACE_SYNAPS
00012 //--------------------------------------------------------------------
00013 namespace numerics
00014 {
00015   /* epsilon<T>::result is a numerical zero */
00016   struct false_t{};
00017   struct true_t {};
00018   template < typename T > struct inexact { typedef false_t result_t; };
00019   template <> struct inexact<long double>{ typedef true_t  result_t; };
00020   template < typename T > struct epsilon { 
00021     static T result;  
00022     static T _init_(const true_t&) {
00023       volatile T  half(0.5), curr(1.0), one(1.0), prev, eps(1.0);
00024       do 
00025         { 
00026           prev = curr;
00027           eps *= half;
00028           curr = one+eps;
00029         } 
00030       while ((curr!=1.0)&&(curr!=prev));
00031       return eps;
00032     };
00033     static T _init_(const false_t&) { return T(0); };
00034     static T _init_() { return _init_(typename inexact< typename LongVersion<T>::result_t >::result_t()); };
00035   };
00036   template < typename T > T epsilon<T>::result = epsilon<T>::_init_();
00037 };
00038 //--------------------------------------------------------------------
00039 __END_NAMESPACE_SYNAPS
00040 /********************************************************************/
00041 #endif //

SYNAPS DOCUMENTATION
logo