dust3d/thirdparty/cgal/CGAL-4.13/include/CGAL/long_double.h

168 lines
4.9 KiB
C
Raw Normal View History

// Copyright (c) 2005,2007
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
//
// Author(s) : Sylvain Pion, Michael Hemmer
#ifndef CGAL_LONG_DOUBLE_H
#define CGAL_LONG_DOUBLE_H
#include <CGAL/number_type_basic.h>
#include <utility>
#include <cmath>
#ifdef CGAL_CFG_IEEE_754_BUG
# include <CGAL/IEEE_754_unions.h>
#endif
// #include <CGAL/FPU.h>
#include <CGAL/Interval_nt.h>
namespace CGAL {
// Is_valid moved to top, since used by is_finite
#ifdef CGAL_CFG_IEEE_754_BUG
#define CGAL_EXPONENT_DOUBLE_MASK 0x7ff00000
#define CGAL_MANTISSA_DOUBLE_MASK 0x000fffff
inline
bool
is_finite_by_mask_long_double(unsigned int h)
{
unsigned int e = h & CGAL_EXPONENT_DOUBLE_MASK;
return ( ( e ^ CGAL_EXPONENT_DOUBLE_MASK ) != 0 );
}
inline
bool
is_nan_by_mask_long_double(unsigned int h, unsigned int l)
{
if ( is_finite_by_mask_long_double(h) )
return false;
return (( h & CGAL_MANTISSA_DOUBLE_MASK ) != 0) || (( l & 0xffffffff ) != 0);
}
template<>
class Is_valid< long double >
: public CGAL::cpp98::unary_function< long double, bool > {
public :
bool operator()( const long double& x ) const {
double d = x;
IEEE_754_double* p = reinterpret_cast<IEEE_754_double*>(&d);
return ! ( is_nan_by_mask_long_double( p->c.H, p->c.L ));
}
};
#else
template<>
class Is_valid< long double >
: public CGAL::cpp98::unary_function< long double, bool > {
public :
bool operator()( const long double& x ) const {
return (x == x);
}
};
#endif
template <> class Algebraic_structure_traits< long double >
: public Algebraic_structure_traits_base< long double,
Field_with_kth_root_tag > {
public:
typedef Tag_false Is_exact;
typedef Tag_true Is_numerical_sensitive;
class Sqrt
: public CGAL::cpp98::unary_function< Type, Type > {
public:
Type operator()( const Type& x ) const {
return std::sqrt( x );
}
};
class Kth_root
:public CGAL::cpp98::binary_function<int, Type, Type > {
public:
Type operator()( int k,
const Type& x) const {
CGAL_precondition_msg( k > 0,
"'k' must be positive for k-th roots");
return std::pow(x, (long double)1.0 / (long double)(k));
};
};
};
template <> class Real_embeddable_traits< long double >
: public INTERN_RET::Real_embeddable_traits_base< long double , CGAL::Tag_true > {
public:
class To_interval
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
public:
std::pair<double, double> operator()( const Type& x ) const {
// The conversion long double to double does not always follow the
// rounding mode (e.g. on MacIntel/g++-4.0.2). So let's do a naive
// conversion to double, then widen the interval.
return (Interval_nt<>((double)x)+Interval_nt<>::smallest()).pair();
#if 0
// We hope that the long double -> double conversion
// follows the current rounding mode.
Protect_FPU_rounding<true> P(CGAL_FE_UPWARD);
volatile long double mx = -x; // needed otherwise the conversion can
// get factorized between d and -d...
if (x>0)
return std::make_pair(- static_cast<double>(CGAL_IA_FORCE_TO_DOUBLE(mx)),
static_cast<double>(CGAL_IA_FORCE_TO_DOUBLE(x)));
else
return std::make_pair((double) CGAL_IA_FORCE_TO_DOUBLE(x),
- (double) CGAL_IA_FORCE_TO_DOUBLE(mx));
#endif
}
};
// Is_finite depends on platform
class Is_finite
: public CGAL::cpp98::unary_function< Type, bool > {
public:
bool operator()( const Type& x ) const {
#ifdef CGAL_CFG_IEEE_754_BUG
Type d = x;
IEEE_754_double* p = reinterpret_cast<IEEE_754_double*>(&d);
return is_finite_by_mask_long_double( p->c.H );
#else
return (x == x) && (is_valid(x-x));
#endif
}
};
};
} //namespace CGAL
#endif // CGAL_LONG_DOUBLE_H