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();
164 #if GEOGRAPHICLIB_PRECISION != 5 167 mpfr::mpreal::set_default_prec(ndigits >= 2 ? ndigits : 2);
176 #if GEOGRAPHICLIB_PRECISION != 5 177 return std::numeric_limits<real>::digits10;
179 return std::numeric_limits<real>::digits10();
189 digits10() > std::numeric_limits<double>::digits10 ?
190 digits10() - std::numeric_limits<double>::digits10 : 0;
202 template<
typename T>
static inline T
pi() {
204 static const T pi = atan2(T(0), T(-1));
210 static inline real
pi() {
return pi<real>(); }
216 template<
typename T>
static inline T
degree() {
217 static const T degree = pi<T>() / 180;
223 static inline real
degree() {
return degree<real>(); }
232 template<
typename T>
static inline T
sq(T x)
243 template<
typename T>
static inline T
hypot(T x, T y) {
244 #if GEOGRAPHICLIB_CXX11_MATH 245 using std::hypot;
return hypot(x, y);
247 using std::abs;
using std::sqrt;
248 x = abs(x); y = abs(y);
249 if (x < y) std::swap(x, y);
251 return x * sqrt(1 + y * y);
265 template<
typename T>
static inline T
expm1(T x) {
266 #if GEOGRAPHICLIB_CXX11_MATH 267 using std::expm1;
return expm1(x);
269 using std::exp;
using std::abs;
using std::log;
277 return abs(x) > 1 ? z : (z == 0 ? x : x * z / log(y));
288 template<
typename T>
static inline T
log1p(T x) {
289 #if GEOGRAPHICLIB_CXX11_MATH 290 using std::log1p;
return log1p(x);
300 return z == 0 ? x : x * log(y) / z;
311 template<
typename T>
static inline T
asinh(T x) {
312 #if GEOGRAPHICLIB_CXX11_MATH 313 using std::asinh;
return asinh(x);
315 using std::abs; T y = abs(x);
316 y = log1p(y * (1 + y/(hypot(T(1), y) + 1)));
317 return x < 0 ? -y : y;
328 template<
typename T>
static inline T
atanh(T x) {
329 #if GEOGRAPHICLIB_CXX11_MATH 330 using std::atanh;
return atanh(x);
332 using std::abs; T y = abs(x);
333 y = log1p(2 * y/(1 - y))/2;
334 return x < 0 ? -y : y;
345 template<
typename T>
static inline T
cbrt(T x) {
346 #if GEOGRAPHICLIB_CXX11_MATH 347 using std::cbrt;
return cbrt(x);
349 using std::abs;
using std::pow;
350 T y = pow(abs(x), 1/T(3));
351 return x < 0 ? -y : y;
369 template<
typename T>
static inline T
fma(T x, T y, T z) {
370 #if GEOGRAPHICLIB_CXX11_MATH 371 using std::fma;
return fma(x, y, z);
384 template<
typename T>
static inline void norm(T& x, T& y)
385 { T h = hypot(x, y); x /= h; y /= h; }
399 template<
typename T>
static inline T
sum(T u, T v, T& t) {
425 template<
typename T>
static inline T
polyval(
int N,
const T p[], T x)
426 { T y = N < 0 ? 0 : *p++;
while (--N >= 0) y = y * x + *p++;
return y; }
438 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION != 4 439 using std::remainder;
440 x = remainder(x, T(360));
return x != 180 ? x : -180;
444 return x < -180 ? x + 360 : (x < 180 ? x : x - 360);
456 template<
typename T>
static inline T
LatFix(T x)
457 {
using std::abs;
return abs(x) > 90 ? NaN<T>() : x; }
475 template<
typename T>
static inline T
AngDiff(T x, T y, T& e) {
476 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION != 4 477 using std::remainder;
478 T t, d = - AngNormalize(sum(remainder( x, T(360)),
479 remainder(-y, T(360)), t));
481 T t, d = - AngNormalize(sum(AngNormalize(x), AngNormalize(-y), t));
489 return sum(d == 180 && t < 0 ? -180 : d, -t, e);
506 template<
typename T>
static inline T
AngDiff(T x, T y)
507 { T e;
return AngDiff(x, y, e); }
524 template<
typename T>
static inline T
AngRound(T x) {
526 static const T z = 1/T(16);
527 if (x == 0)
return 0;
530 y = y < z ? z - (z - y) : y;
531 return x < 0 ? -y : y;
545 template<
typename T>
static inline void sincosd(T x, T& sinx, T& cosx) {
548 using std::sin;
using std::cos;
550 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \ 559 r = remquo(x, T(90), &q);
561 using std::fmod;
using std::floor;
563 q = int(floor(r / 90 + T(0.5)));
569 T s = sin(r), c = cos(r);
570 #if defined(_MSC_VER) && _MSC_VER < 1900 577 switch (
unsigned(q) & 3U) {
578 case 0U: sinx = s; cosx = c;
break;
579 case 1U: sinx = c; cosx = T(0) - s;
break;
580 case 2U: sinx = T(0) - s; cosx = T(0) - c;
break;
581 default: sinx = T(0) - c; cosx = s;
break;
592 template<
typename T>
static inline T
sind(T x) {
594 using std::sin;
using std::cos;
596 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \ 599 r = remquo(x, T(90), &q);
601 using std::fmod;
using std::floor;
603 q = int(floor(r / 90 + T(0.5)));
608 unsigned p = unsigned(q);
609 r = p & 1U ? cos(r) : sin(r);
610 return p & 2U ? T(0) - r : r;
620 template<
typename T>
static inline T
cosd(T x) {
622 using std::sin;
using std::cos;
624 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \ 627 r = remquo(x, T(90), &q);
629 using std::fmod;
using std::floor;
631 q = int(floor(r / 90 + T(0.5)));
636 unsigned p = unsigned(q + 1);
637 r = p & 1U ? cos(r) : sin(r);
638 return p & 2U ? T(0) - r : r;
651 template<
typename T>
static inline T
tand(T x) {
652 static const T overflow = 1 / sq(std::numeric_limits<T>::epsilon());
655 return c ? s / c : (s < 0 ? -overflow : overflow);
671 template<
typename T>
static inline T
atan2d(T y, T x) {
676 using std::atan2;
using std::abs;
678 if (abs(y) > abs(x)) { std::swap(x, y); q = 2; }
679 if (x < 0) { x = -x; ++q; }
681 T ang = atan2(y, x) / degree();
689 case 1: ang = (y > 0 ? 180 : -180) - ang;
break;
690 case 2: ang = 90 - ang;
break;
691 case 3: ang = -90 + ang;
break;
703 template<
typename T>
static inline T
atand(T x)
704 {
return atan2d(x, T(1)); }
718 template<
typename T>
static T eatanhe(T x, T es);
728 template<
typename T>
static inline T
copysign(T x, T y) {
729 #if GEOGRAPHICLIB_CXX11_MATH 730 using std::copysign;
return copysign(x, y);
732 using std::abs;
using std::atan2;
734 return abs(x) * (y < 0 || (y == 0 && 1/y < 0) ? -1 : 1);
754 template<
typename T>
static T taupf(T tau, T es);
772 template<
typename T>
static T tauf(T taup, T es);
781 template<
typename T>
static inline bool isfinite(T x) {
782 #if GEOGRAPHICLIB_CXX11_MATH 783 using std::isfinite;
return isfinite(x);
786 #if defined(_MSC_VER) 787 return abs(x) <= (std::numeric_limits<T>::max)();
794 return abs(x) <= std::numeric_limits<T>::max();
805 template<
typename T>
static inline T
NaN() {
806 #if defined(_MSC_VER) 807 return std::numeric_limits<T>::has_quiet_NaN ?
808 std::numeric_limits<T>::quiet_NaN() :
809 (std::numeric_limits<T>::max)();
811 return std::numeric_limits<T>::has_quiet_NaN ?
812 std::numeric_limits<T>::quiet_NaN() :
813 std::numeric_limits<T>::max();
819 static inline real
NaN() {
return NaN<real>(); }
828 template<
typename T>
static inline bool isnan(T x) {
829 #if GEOGRAPHICLIB_CXX11_MATH 830 using std::isnan;
return isnan(x);
843 #if defined(_MSC_VER) 844 return std::numeric_limits<T>::has_infinity ?
845 std::numeric_limits<T>::infinity() :
846 (std::numeric_limits<T>::max)();
848 return std::numeric_limits<T>::has_infinity ?
849 std::numeric_limits<T>::infinity() :
850 std::numeric_limits<T>::max();
856 static inline real
infinity() {
return infinity<real>(); }
865 template<
typename T>
static inline T
swab(T x) {
868 unsigned char c[
sizeof(T)];
871 for (
int i =
sizeof(T)/2; i--; )
872 std::swap(b.c[i], b.c[
sizeof(T) - 1 - i]);
876 #if GEOGRAPHICLIB_PRECISION == 4 877 typedef boost::math::policies::policy
878 < boost::math::policies::domain_error
879 <boost::math::policies::errno_on_error>,
880 boost::math::policies::pole_error
881 <boost::math::policies::errno_on_error>,
882 boost::math::policies::overflow_error
883 <boost::math::policies::errno_on_error>,
884 boost::math::policies::evaluation_error
885 <boost::math::policies::errno_on_error> >
886 boost_special_functions_policy;
888 static inline real hypot(real x, real y)
889 {
return boost::math::hypot(x, y, boost_special_functions_policy()); }
891 static inline real expm1(real x)
892 {
return boost::math::expm1(x, boost_special_functions_policy()); }
894 static inline real log1p(real x)
895 {
return boost::math::log1p(x, boost_special_functions_policy()); }
897 static inline real asinh(real x)
898 {
return boost::math::asinh(x, boost_special_functions_policy()); }
900 static inline real atanh(real x)
901 {
return boost::math::atanh(x, boost_special_functions_policy()); }
903 static inline real cbrt(real x)
904 {
return boost::math::cbrt(x, boost_special_functions_policy()); }
906 static inline real fma(real x, real y, real z)
907 {
return fmaq(__float128(x), __float128(y), __float128(z)); }
909 static inline real copysign(real x, real y)
910 {
return boost::math::copysign(x, y); }
912 static inline bool isnan(real x) {
return boost::math::isnan(x); }
914 static inline bool isfinite(real x) {
return boost::math::isfinite(x); }
920 #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 sincosd(T x, T &sinx, T &cosx)
static T AngDiff(T x, T y, T &e)
static void norm(T &x, T &y)
#define GEOGRAPHICLIB_PRECISION
#define GEOGRAPHICLIB_VOLATILE
static int extra_digits()
static T atan2d(T y, T x)
static T polyval(int N, const T p[], T x)
Namespace for GeographicLib.
static T AngDiff(T x, T y)
static T copysign(T x, T y)
Header for GeographicLib::Constants class.
static T fma(T x, T y, T z)