14 #if !defined(GEOGRAPHICLIB_MATH_HPP)
15 #define GEOGRAPHICLIB_MATH_HPP 1
20 #if !defined(GEOGRAPHICLIB_CXX11_MATH)
28 # if defined(__GNUC__) && __cplusplus >= 201103 && \
29 !(defined(__ANDROID__) || defined(ANDROID) || defined(__CYGWIN__))
30 # define GEOGRAPHICLIB_CXX11_MATH 1
32 # elif defined(_MSC_VER) && _MSC_VER >= 1800
33 # define GEOGRAPHICLIB_CXX11_MATH 1
35 # define GEOGRAPHICLIB_CXX11_MATH 0
39 #if !defined(GEOGRAPHICLIB_WORDS_BIGENDIAN)
40 # define GEOGRAPHICLIB_WORDS_BIGENDIAN 0
43 #if !defined(GEOGRAPHICLIB_HAVE_LONG_DOUBLE)
44 # define GEOGRAPHICLIB_HAVE_LONG_DOUBLE 0
47 #if !defined(GEOGRAPHICLIB_PRECISION)
57 # define GEOGRAPHICLIB_PRECISION 2
64 #if GEOGRAPHICLIB_PRECISION == 4
65 #include <boost/version.hpp>
66 #if BOOST_VERSION >= 105600
67 #include <boost/cstdfloat.hpp>
69 #include <boost/multiprecision/float128.hpp>
70 #include <boost/math/special_functions.hpp>
71 __float128 fmaq(__float128, __float128, __float128);
72 #elif GEOGRAPHICLIB_PRECISION == 5
76 #if GEOGRAPHICLIB_PRECISION > 3
78 #define GEOGRAPHICLIB_VOLATILE
81 #define GEOGRAPHICLIB_PANIC \
82 (throw GeographicLib::GeographicErr("Convergence failure"), false)
84 #define GEOGRAPHICLIB_VOLATILE volatile
87 #define GEOGRAPHICLIB_PANIC false
107 "Bad value of precision");
112 #if GEOGRAPHICLIB_HAVE_LONG_DOUBLE
122 #if GEOGRAPHICLIB_PRECISION == 2
130 #elif GEOGRAPHICLIB_PRECISION == 1
132 #elif GEOGRAPHICLIB_PRECISION == 3
133 typedef extended
real;
134 #elif GEOGRAPHICLIB_PRECISION == 4
135 typedef boost::multiprecision::float128
real;
136 #elif GEOGRAPHICLIB_PRECISION == 5
137 typedef mpfr::mpreal
real;
146 #if GEOGRAPHICLIB_PRECISION != 5
147 return std::numeric_limits<real>::digits;
149 return std::numeric_limits<real>::digits();
162 #if GEOGRAPHICLIB_PRECISION != 5
165 mpfr::mpreal::set_default_prec(ndigits >= 2 ? ndigits : 2);
174 #if GEOGRAPHICLIB_PRECISION != 5
175 return std::numeric_limits<real>::digits10;
177 return std::numeric_limits<real>::digits10();
187 digits10() > std::numeric_limits<double>::digits10 ?
188 digits10() - std::numeric_limits<double>::digits10 : 0;
191 #if GEOGRAPHICLIB_PRECISION <= 3
198 static const int extradigits =
199 std::numeric_limits<real>::digits10 >
200 std::numeric_limits<double>::digits10 ?
201 std::numeric_limits<real>::digits10 -
202 std::numeric_limits<double>::digits10 : 0;
214 template<
typename T>
static inline T
pi() {
216 static const T pi = atan2(T(0), T(-1));
222 static inline real
pi() {
return pi<real>(); }
228 template<
typename T>
static inline T
degree() {
229 static const T degree = pi<T>() / 180;
235 static inline real
degree() {
return degree<real>(); }
244 template<
typename T>
static inline T
sq(T x)
255 template<
typename T>
static inline T
hypot(T x, T y) {
256 #if GEOGRAPHICLIB_CXX11_MATH
257 using std::hypot;
return hypot(x, y);
259 using std::abs;
using std::sqrt;
260 x = abs(x); y = abs(y);
261 if (x < y) std::swap(x, y);
263 return x * sqrt(1 + y * y);
277 template<
typename T>
static inline T
expm1(T x) {
278 #if GEOGRAPHICLIB_CXX11_MATH
279 using std::expm1;
return expm1(x);
281 using std::exp;
using std::abs;
using std::log;
289 return abs(x) > 1 ? z : (z == 0 ? x : x * z / log(y));
300 template<
typename T>
static inline T
log1p(T x) {
301 #if GEOGRAPHICLIB_CXX11_MATH
302 using std::log1p;
return log1p(x);
312 return z == 0 ? x : x * log(y) / z;
323 template<
typename T>
static inline T
asinh(T x) {
324 #if GEOGRAPHICLIB_CXX11_MATH
325 using std::asinh;
return asinh(x);
327 using std::abs; T y = abs(x);
328 y = log1p(y * (1 + y/(hypot(T(1), y) + 1)));
329 return x < 0 ? -y : y;
340 template<
typename T>
static inline T
atanh(T x) {
341 #if GEOGRAPHICLIB_CXX11_MATH
342 using std::atanh;
return atanh(x);
344 using std::abs; T y = abs(x);
345 y = log1p(2 * y/(1 - y))/2;
346 return x < 0 ? -y : y;
357 template<
typename T>
static inline T
cbrt(T x) {
358 #if GEOGRAPHICLIB_CXX11_MATH
359 using std::cbrt;
return cbrt(x);
361 using std::abs;
using std::pow;
362 T y = pow(abs(x), 1/T(3));
363 return x < 0 ? -y : y;
377 template<
typename T>
static inline T
fma(T x, T y, T z) {
378 #if GEOGRAPHICLIB_CXX11_MATH
379 using std::fma;
return fma(x, y, z);
392 template<
typename T>
static inline void norm(T& x, T& y)
393 { T h = hypot(x, y); x /= h; y /= h; }
407 template<
typename T>
static inline T
sum(T u, T v, T& t) {
429 {
return x >= 180 ? x - 360 : (x < -180 ? x + 360 : x); }
441 {
using std::fmod;
return AngNormalize<T>(fmod(x, T(360))); }
458 template<
typename T>
static inline T
AngDiff(T x, T y) {
459 T t, d = sum(-x, y, t);
460 if ((d - T(180)) + t > T(0))
462 else if ((d + T(180)) + t <= T(0))
481 template<
typename T>
static inline T
AngRound(T x) {
486 y = y < z ? z - (z - y) : y;
487 return x < 0 ? -y : y;
500 template<
typename T>
static inline T
tand(T x) {
501 using std::abs;
using std::tan;
502 static const T overflow = 1 /
Math::sq(std::numeric_limits<T>::epsilon());
504 (x < 0 ? -overflow : overflow);
516 template<
typename T>
static inline T
atand(T x) {
517 using std::abs;
using std::atan;
519 overflow = 1 / (
Math::sq(std::numeric_limits<T>::epsilon()) * 100);
520 return !(abs(x) >= overflow) ? atan(x) /
Math::degree() :
534 template<
typename T>
static inline T
atan2d(T y, T x) {
551 template<
typename T>
static T eatanhe(T x, T es);
569 template<
typename T>
static T taupf(T tau, T es);
587 template<
typename T>
static T tauf(T taup, T es);
596 template<
typename T>
static inline bool isfinite(T x) {
597 #if GEOGRAPHICLIB_CXX11_MATH
598 using std::isfinite;
return isfinite(x);
601 return abs(x) <= (std::numeric_limits<T>::max)();
611 template<
typename T>
static inline T
NaN() {
612 return std::numeric_limits<T>::has_quiet_NaN ?
613 std::numeric_limits<T>::quiet_NaN() :
614 (std::numeric_limits<T>::max)();
619 static inline real
NaN() {
return NaN<real>(); }
628 template<
typename T>
static inline bool isnan(T x) {
629 #if GEOGRAPHICLIB_CXX11_MATH
630 using std::isnan;
return isnan(x);
643 return std::numeric_limits<T>::has_infinity ?
644 std::numeric_limits<T>::infinity() :
645 (std::numeric_limits<T>::max)();
650 static inline real
infinity() {
return infinity<real>(); }
659 template<
typename T>
static inline T
swab(T x) {
662 unsigned char c[
sizeof(T)];
665 for (
int i =
sizeof(T)/2; i--; )
666 std::swap(b.c[i], b.c[
sizeof(T) - 1 - i]);
670 #if GEOGRAPHICLIB_PRECISION == 4
671 typedef boost::math::policies::policy
672 < boost::math::policies::domain_error
673 <boost::math::policies::errno_on_error>,
674 boost::math::policies::pole_error
675 <boost::math::policies::errno_on_error>,
676 boost::math::policies::overflow_error
677 <boost::math::policies::errno_on_error>,
678 boost::math::policies::evaluation_error
679 <boost::math::policies::errno_on_error> >
680 boost_special_functions_policy;
682 static inline real hypot(real x, real y)
683 {
return boost::math::hypot(x, y, boost_special_functions_policy()); }
685 static inline real expm1(real x)
686 {
return boost::math::expm1(x, boost_special_functions_policy()); }
688 static inline real log1p(real x)
689 {
return boost::math::log1p(x, boost_special_functions_policy()); }
691 static inline real asinh(real x)
692 {
return boost::math::asinh(x, boost_special_functions_policy()); }
694 static inline real atanh(real x)
695 {
return boost::math::atanh(x, boost_special_functions_policy()); }
697 static inline real cbrt(real x)
698 {
return boost::math::cbrt(x, boost_special_functions_policy()); }
700 static inline real fma(real x, real y, real z)
701 {
return fmaq(__float128(x), __float128(y), __float128(z)); }
703 static inline bool isnan(real x) {
return boost::math::isnan(x); }
705 static inline bool isfinite(real x) {
return boost::math::isfinite(x); }
711 #endif // GEOGRAPHICLIB_MATH_HPP
static T AngNormalize(T x)
static T sum(T u, T v, T &t)
static int set_digits(int ndigits)
#define GEOGRAPHICLIB_EXPORT
#define GEOGRAPHICLIB_WORDS_BIGENDIAN
GeographicLib::Math::real real
static bool isfinite(T x)
Mathematical functions needed by GeographicLib.
static void norm(T &x, T &y)
#define GEOGRAPHICLIB_PRECISION
#define GEOGRAPHICLIB_VOLATILE
static int extra_digits()
static T atan2d(T y, T x)
Namespace for GeographicLib.
static T AngDiff(T x, T y)
Header for GeographicLib::Constants class.
static T fma(T x, T y, T z)
static T AngNormalize2(T x)