BWAPI
|
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