BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/long_double.h
Go to the documentation of this file.
00001 // Copyright (c) 2005,2007  Utrecht University (The Netherlands),
00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),
00005 // and Tel-Aviv University (Israel).  All rights reserved.
00006 //
00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public License as
00009 // published by the Free Software Foundation; version 2.1 of the License.
00010 // See the file LICENSE.LGPL distributed with CGAL.
00011 //
00012 // Licensees holding a valid commercial license may use this file in
00013 // accordance with the commercial license agreement provided with the software.
00014 //
00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 //
00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Number_types/include/CGAL/long_double.h $
00019 // $Id: long_double.h 44911 2008-08-12 13:09:51Z spion $
00020 //
00021 //
00022 // Author(s)     : Sylvain Pion, Michael Hemmer
00023 
00024 #ifndef CGAL_LONG_DOUBLE_H
00025 #define CGAL_LONG_DOUBLE_H
00026 
00027 #include <CGAL/number_type_basic.h>
00028 
00029 #include <utility>
00030 #include <cmath>
00031 #ifdef CGAL_CFG_IEEE_754_BUG
00032 #  include <CGAL/IEEE_754_unions.h>
00033 #endif
00034 
00035 // #include <CGAL/FPU.h>
00036 #include <CGAL/Interval_nt.h>
00037 
00038 CGAL_BEGIN_NAMESPACE
00039 
00040 // Is_valid moved to top, since used by is_finite
00041 #ifdef CGAL_CFG_IEEE_754_BUG
00042 
00043 #define CGAL_EXPONENT_DOUBLE_MASK   0x7ff00000
00044 #define CGAL_MANTISSA_DOUBLE_MASK   0x000fffff
00045 
00046 inline
00047 bool
00048 is_finite_by_mask_long_double(unsigned int h)
00049 {
00050   unsigned int e = h & CGAL_EXPONENT_DOUBLE_MASK;
00051   return ( ( e ^ CGAL_EXPONENT_DOUBLE_MASK ) != 0 );
00052 }
00053 
00054 inline
00055 bool
00056 is_nan_by_mask_long_double(unsigned int h, unsigned int l)
00057 {
00058   if ( is_finite_by_mask_long_double(h) )
00059       return false;
00060   return (( h & CGAL_MANTISSA_DOUBLE_MASK ) != 0) || (( l & 0xffffffff ) != 0);
00061 }
00062 
00063 template<>
00064 class Is_valid< long double >
00065   : public std::unary_function< long double, bool > {
00066   public :
00067     bool operator()( const long double& x ) const {
00068       double d = x;
00069       IEEE_754_double* p = reinterpret_cast<IEEE_754_double*>(&d);
00070       return ! ( is_nan_by_mask_long_double( p->c.H, p->c.L ));
00071     }
00072 };
00073 
00074 #else
00075 
00076 template<>
00077 class Is_valid< long double >
00078   : public std::unary_function< long double, bool > {
00079   public :
00080     bool operator()( const long double& x ) const {
00081       return (x == x);
00082     }
00083 };
00084 
00085 #endif
00086 
00087 
00088 
00089 
00090 template <> class Algebraic_structure_traits< long double >
00091   : public Algebraic_structure_traits_base< long double,
00092                                             Field_with_kth_root_tag >  {
00093   public:
00094     typedef Tag_false            Is_exact;
00095     typedef Tag_true             Is_numerical_sensitive;
00096 
00097     class Sqrt
00098       : public std::unary_function< Type, Type > {
00099       public:
00100         Type operator()( const Type& x ) const {
00101           return std::sqrt( x );
00102         }
00103     };
00104 
00105     class Kth_root
00106       :public std::binary_function<int, Type, Type > {
00107       public:
00108         Type operator()( int k,
00109                                         const Type& x) const {
00110           CGAL_precondition_msg( k > 0,
00111                                     "'k' must be positive for k-th roots");
00112           return std::pow(x, (long double)1.0 / (long double)(k));
00113         };
00114     };
00115 
00116 };
00117 
00118 template <> class Real_embeddable_traits< long double >
00119   : public INTERN_RET::Real_embeddable_traits_base< long double , CGAL::Tag_true > {
00120   public:
00121 
00122     class To_interval
00123       : public std::unary_function< Type, std::pair< double, double > > {
00124       public:
00125         std::pair<double, double> operator()( const Type& x ) const {
00126           // The conversion long double to double does not always follow the
00127           // rounding mode (e.g. on MacIntel/g++-4.0.2).  So let's do a naive
00128           // conversion to double, then widen the interval.
00129           return (Interval_nt<>((double)x)+Interval_nt<>::smallest()).pair();
00130 #if 0
00131           // We hope that the long double -> double conversion
00132           // follows the current rounding mode.
00133           Protect_FPU_rounding<true> P(CGAL_FE_UPWARD);
00134           volatile long double mx = -x; // needed otherwise the conversion can
00135                                         // get factorized between d and -d...
00136           if (x>0)
00137             return std::make_pair(- static_cast<double>(CGAL_IA_FORCE_TO_DOUBLE(mx)),
00138                                   static_cast<double>(CGAL_IA_FORCE_TO_DOUBLE(x)));
00139           else
00140             return std::make_pair((double) CGAL_IA_FORCE_TO_DOUBLE(x),
00141                                   - (double) CGAL_IA_FORCE_TO_DOUBLE(mx));
00142 #endif
00143         }
00144     };
00145 
00146 // Is_finite depends on platform
00147     class Is_finite
00148       : public std::unary_function< Type, bool > {
00149       public:
00150         bool operator()( const Type& x ) const {
00151 #ifdef CGAL_CFG_IEEE_754_BUG
00152           Type d = x;
00153           IEEE_754_double* p = reinterpret_cast<IEEE_754_double*>(&d);
00154           return is_finite_by_mask_long_double( p->c.H );
00155 #else
00156           return (x == x) && (is_valid(x-x));
00157 #endif
00158         }
00159     };
00160 
00161 };
00162 
00163 CGAL_END_NAMESPACE
00164 
00165 #endif // CGAL_LONG_DOUBLE_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines