BWAPI
|
00001 // Copyright (c) 1999,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/double.h $ 00019 // $Id: double.h 44911 2008-08-12 13:09:51Z spion $ 00020 // 00021 // 00022 // Author(s) : Geert-Jan Giezeman, Michael Hemmer 00023 00024 #ifndef CGAL_DOUBLE_H 00025 #define CGAL_DOUBLE_H 00026 00027 #include <CGAL/number_type_basic.h> 00028 00029 #include <utility> 00030 #include <cmath> 00031 #include <math.h> // for nextafter 00032 #include <limits> 00033 00034 00035 #ifdef _MSC_VER 00036 #include <cfloat> 00037 #endif 00038 00039 #ifdef CGAL_CFG_IEEE_754_BUG 00040 # include <CGAL/IEEE_754_unions.h> 00041 #endif 00042 00043 CGAL_BEGIN_NAMESPACE 00044 00045 #ifdef CGAL_CFG_IEEE_754_BUG 00046 00047 #define CGAL_EXPONENT_DOUBLE_MASK 0x7ff00000 00048 #define CGAL_MANTISSA_DOUBLE_MASK 0x000fffff 00049 00050 inline 00051 bool 00052 is_finite_by_mask_double(unsigned int h) 00053 { 00054 unsigned int e = h & CGAL_EXPONENT_DOUBLE_MASK; 00055 return ( ( e ^ CGAL_EXPONENT_DOUBLE_MASK ) != 0 ); 00056 } 00057 00058 inline 00059 bool 00060 is_nan_by_mask_double(unsigned int h, unsigned int l) 00061 { 00062 if ( is_finite_by_mask_double(h) ) 00063 return false; 00064 return (( h & CGAL_MANTISSA_DOUBLE_MASK ) != 0) || (( l & 0xffffffff ) != 0); 00065 } 00066 00067 template<> 00068 class Is_valid< double > 00069 : public std::unary_function< double, bool > { 00070 public : 00071 bool operator()( const double& x ) const{ 00072 double d = x; 00073 IEEE_754_double* p = reinterpret_cast<IEEE_754_double*>(&d); 00074 return ! ( is_nan_by_mask_double( p->c.H, p->c.L )); 00075 } 00076 }; 00077 00078 #else 00079 00080 template<> 00081 class Is_valid< double > 00082 : public std::unary_function< double, bool > { 00083 public : 00084 bool operator()( const double& x ) const { 00085 #ifdef _MSC_VER 00086 return ! _isnan(x); 00087 #else 00088 return (x == x); 00089 #endif 00090 } 00091 }; 00092 00093 #endif 00094 00095 template <> class Algebraic_structure_traits< double > 00096 : public Algebraic_structure_traits_base< double, 00097 Field_with_kth_root_tag > { 00098 public: 00099 typedef Tag_false Is_exact; 00100 typedef Tag_true Is_numerical_sensitive; 00101 00102 class Sqrt 00103 : public std::unary_function< Type, Type > { 00104 public: 00105 Type operator()( const Type& x ) const { 00106 return std::sqrt( x ); 00107 } 00108 }; 00109 00110 class Kth_root 00111 : public std::binary_function<int, Type, Type> { 00112 public: 00113 Type operator()( int k, 00114 const Type& x) const { 00115 CGAL_precondition_msg( k > 0, "'k' must be positive for k-th roots"); 00116 return std::pow(x, 1.0 / double(k)); 00117 } 00118 }; 00119 00120 }; 00121 00122 template <> class Real_embeddable_traits< double > 00123 : public INTERN_RET::Real_embeddable_traits_base< double , CGAL::Tag_true> { 00124 public: 00125 00126 // GCC is faster with std::fabs(). 00127 #ifdef __GNUG__ 00128 class Abs 00129 : public std::unary_function< Type, Type > { 00130 public: 00131 Type operator()( const Type& x ) const { 00132 return std::fabs( x ); 00133 } 00134 }; 00135 #endif 00136 00137 // Is_finite depends on platform 00138 class Is_finite 00139 : public std::unary_function< Type, bool > { 00140 public : 00141 bool operator()( const Type& x ) const { 00142 #ifdef CGAL_CFG_IEEE_754_BUG 00143 Type d = x; 00144 IEEE_754_double* p = reinterpret_cast<IEEE_754_double*>(&d); 00145 return is_finite_by_mask_double( p->c.H ); 00146 #elif defined CGAL_CFG_NUMERIC_LIMITS_BUG 00147 return (x == x) && (is_valid(x-x)); 00148 #else 00149 return (x != std::numeric_limits<Type>::infinity()) 00150 && (-x != std::numeric_limits<Type>::infinity()) 00151 && is_valid(x); 00152 #endif 00153 } 00154 }; 00155 }; 00156 00157 inline 00158 double 00159 nextafter(double d1, double d2) 00160 { 00161 #ifdef CGAL_CFG_NO_NEXTAFTER 00162 return _nextafter(d1, d2); // works at least for VC++-7.1 00163 #else 00164 return ::nextafter(d1,d2); 00165 #endif 00166 } 00167 00168 inline 00169 bool 00170 is_integer(double d) 00171 { 00172 return CGAL::is_finite(d) && (std::ceil(d) == d); 00173 } 00174 00175 // Returns a pair of integers <num,den> such that d == num/den. 00176 inline 00177 std::pair<double, double> 00178 split_numerator_denominator(double d) 00179 { 00180 // Note that it could probably be optimized. 00181 double num = d; 00182 double den = 1.0; 00183 while (std::ceil(num) != num) 00184 { 00185 num *= 2.0; 00186 den *= 2.0; 00187 } 00188 CGAL_postcondition(d == num/den); 00189 return std::make_pair(num, den); 00190 } 00191 00192 CGAL_END_NAMESPACE 00193 00194 #endif // CGAL_DOUBLE_H