14 # pragma warning (disable: 4127)
24 "Bad value of precision");
28 #if GEOGRAPHICLIB_PRECISION != 5
29 return std::numeric_limits<real>::digits;
31 return std::numeric_limits<real>::digits();
36 #if GEOGRAPHICLIB_PRECISION != 5
39 mpfr::mpreal::set_default_prec(ndigits >= 2 ? ndigits : 2);
45 #if GEOGRAPHICLIB_PRECISION != 5
46 return std::numeric_limits<real>::digits10;
48 return std::numeric_limits<real>::digits10();
54 digits10() > std::numeric_limits<double>::digits10 ?
55 digits10() - std::numeric_limits<double>::digits10 : 0;
59 #if GEOGRAPHICLIB_CXX11_MATH
60 using std::hypot;
return hypot(x, y);
62 x = abs(x); y = abs(y);
64 y /= (x != 0 ? x : 1);
65 return x * sqrt(1 + y * y);
73 #if GEOGRAPHICLIB_CXX11_MATH
74 using std::expm1;
return expm1(x);
83 return abs(x) > 1 ? z : (z == 0 ? x : x * z / log(y));
88 #if GEOGRAPHICLIB_CXX11_MATH
89 using std::log1p;
return log1p(x);
98 return z == 0 ? x : x * log(y) / z;
103 #if GEOGRAPHICLIB_CXX11_MATH
104 using std::asinh;
return asinh(x);
107 y = log1p(y * (1 + y/(hypot(T(1), y) + 1)));
108 return x > 0 ? y : (x < 0 ? -y : x);
113 #if GEOGRAPHICLIB_CXX11_MATH
114 using std::atanh;
return atanh(x);
117 y = log1p(2 * y/(1 - y))/2;
118 return x > 0 ? y : (x < 0 ? -y : x);
123 #if GEOGRAPHICLIB_CXX11_MATH
124 using std::copysign;
return copysign(x, y);
127 return abs(x) * (y < 0 || (y == 0 && 1/y < 0) ? -1 : 1);
132 #if GEOGRAPHICLIB_CXX11_MATH
133 using std::cbrt;
return cbrt(x);
135 T y = pow(abs(x), 1/T(3));
136 return x > 0 ? y : (x < 0 ? -y : x);
141 #if GEOGRAPHICLIB_CXX11_MATH
142 using std::remainder;
return remainder(x, y);
152 else if (2 * abs(z) == y)
153 z -= fmod(x, 2 * y) - z;
154 else if (2 * abs(z) > y)
155 z += (z < 0 ? y : -y);
162 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3
163 using std::remquo;
return remquo(x, y, n);
165 T z = remainder(x, y);
168 a = remainder(x, 2 * y),
169 b = remainder(x, 4 * y),
170 c = remainder(x, 8 * y);
171 *n = (a > z ? 1 : (a < z ? -1 : 0));
172 *n += (b > a ? 2 : (b < a ? -2 : 0));
173 *n += (c > b ? 4 : (c < b ? -4 : 0));
176 if (x/y > 0 && *n <= 0)
178 else if (x/y < 0 && *n >= 0)
187 #if GEOGRAPHICLIB_CXX11_MATH
188 using std::round;
return round(x);
193 if (0 < x && x < T(0.5))
195 else if (0 > x && x > -T(0.5))
199 return t - x > T(0.5) ? t - 1 : t;
202 return x - t > T(0.5) ? t + 1 : t;
209 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION != 5
210 using std::lround;
return lround(x);
213 long r = std::numeric_limits<long>::min();
222 #if GEOGRAPHICLIB_CXX11_MATH
223 using std::fma;
return fma(x, y, z);
242 static const T z = 1/T(16);
243 if (x == 0)
return 0;
246 y = y < z ? z - (z - y) : y;
247 return x < 0 ? -y : y;
257 r = remquo(x, T(90), &q);
260 T s = sin(r), c = cos(r);
261 #if defined(_MSC_VER) && _MSC_VER < 1900
270 switch (
unsigned(q) & 3U) {
271 case 0U: sinx = s; cosx = c;
break;
272 case 1U: sinx = c; cosx = -s;
break;
273 case 2U: sinx = -s; cosx = -c;
break;
274 default: sinx = -c; cosx = s;
break;
277 if (x != 0) { sinx += T(0); cosx += T(0); }
283 r = remquo(x, T(90), &q);
285 unsigned p = unsigned(q);
286 r = p & 1U ? cos(r) : sin(r);
288 if (x != 0) r += T(0);
295 r = remquo(x, T(90), &q);
297 unsigned p = unsigned(q + 1);
298 r = p & 1U ? cos(r) : sin(r);
304 static const T overflow = 1 / sq(std::numeric_limits<T>::epsilon());
307 return c != 0 ? s / c : (s < 0 ? -overflow : overflow);
316 if (abs(y) > abs(x)) {
std::swap(x, y); q = 2; }
317 if (x < 0) { x = -x; ++q; }
319 T ang = atan2(y, x) / degree<T>();
327 case 1: ang = (y >= 0 ? 180 : -180) - ang;
break;
328 case 2: ang = 90 - ang;
break;
329 case 3: ang = -90 + ang;
break;
335 {
return atan2d(x, T(1)); }
338 return es > T(0) ? es * atanh(es * x) : -es * atan(es * x);
342 T tau1 = hypot(T(1), tau),
343 sig = sinh( eatanhe(tau / tau1, es ) );
344 return hypot(T(1), sig) * tau - sig * tau1;
349 const T tol = sqrt(numeric_limits<T>::epsilon()) / T(10);
350 T e2m = T(1) - sq(es),
359 stol = tol * max(T(1), abs(taup));
362 T taupa = taupf(tau, es),
363 dtau = (taup - taupa) * (1 + e2m * sq(tau)) /
364 ( e2m * hypot(T(1), tau) * hypot(T(1), taupa) );
366 if (!(abs(dtau) >= stol))
373 #if GEOGRAPHICLIB_CXX11_MATH
374 using std::isfinite;
return isfinite(x);
376 #if defined(_MSC_VER)
377 return abs(x) <= (std::numeric_limits<T>::max)();
384 return abs(x) <= std::numeric_limits<T>::max();
390 #if defined(_MSC_VER)
391 return std::numeric_limits<T>::has_quiet_NaN ?
392 std::numeric_limits<T>::quiet_NaN() :
393 (std::numeric_limits<T>::max)();
395 return std::numeric_limits<T>::has_quiet_NaN ?
396 std::numeric_limits<T>::quiet_NaN() :
397 std::numeric_limits<T>::max();
402 #if GEOGRAPHICLIB_CXX11_MATH
403 using std::isnan;
return isnan(x);
410 #if defined(_MSC_VER)
411 return std::numeric_limits<T>::has_infinity ?
412 std::numeric_limits<T>::infinity() :
413 (std::numeric_limits<T>::max)();
415 return std::numeric_limits<T>::has_infinity ?
416 std::numeric_limits<T>::infinity() :
417 std::numeric_limits<T>::max();
423 #define GEOGRAPHICLIB_MATH_INSTANTIATE(T) \
424 template T GEOGRAPHICLIB_EXPORT Math::hypot <T>(T, T); \
425 template T GEOGRAPHICLIB_EXPORT Math::expm1 <T>(T); \
426 template T GEOGRAPHICLIB_EXPORT Math::log1p <T>(T); \
427 template T GEOGRAPHICLIB_EXPORT Math::asinh <T>(T); \
428 template T GEOGRAPHICLIB_EXPORT Math::atanh <T>(T); \
429 template T GEOGRAPHICLIB_EXPORT Math::cbrt <T>(T); \
430 template T GEOGRAPHICLIB_EXPORT Math::remainder<T>(T, T); \
431 template T GEOGRAPHICLIB_EXPORT Math::remquo <T>(T, T, int*); \
432 template T GEOGRAPHICLIB_EXPORT Math::round <T>(T); \
433 template long GEOGRAPHICLIB_EXPORT Math::lround <T>(T); \
434 template T GEOGRAPHICLIB_EXPORT Math::copysign <T>(T, T); \
435 template T GEOGRAPHICLIB_EXPORT Math::fma <T>(T, T, T); \
436 template T GEOGRAPHICLIB_EXPORT Math::sum <T>(T, T, T&); \
437 template T GEOGRAPHICLIB_EXPORT Math::AngRound <T>(T); \
438 template void GEOGRAPHICLIB_EXPORT Math::sincosd <T>(T, T&, T&); \
439 template T GEOGRAPHICLIB_EXPORT Math::sind <T>(T); \
440 template T GEOGRAPHICLIB_EXPORT Math::cosd <T>(T); \
441 template T GEOGRAPHICLIB_EXPORT Math::tand <T>(T); \
442 template T GEOGRAPHICLIB_EXPORT Math::atan2d <T>(T, T); \
443 template T GEOGRAPHICLIB_EXPORT Math::atand <T>(T); \
444 template T GEOGRAPHICLIB_EXPORT Math::eatanhe <T>(T, T); \
445 template T GEOGRAPHICLIB_EXPORT Math::taupf <T>(T, T); \
446 template T GEOGRAPHICLIB_EXPORT Math::tauf <T>(T, T); \
447 template bool GEOGRAPHICLIB_EXPORT Math::isfinite <T>(T); \
448 template T GEOGRAPHICLIB_EXPORT Math::NaN <T>(); \
449 template bool GEOGRAPHICLIB_EXPORT Math::isnan <T>(T); \
450 template T GEOGRAPHICLIB_EXPORT Math::infinity <T>();
453 GEOGRAPHICLIB_MATH_INSTANTIATE(
float)
454 GEOGRAPHICLIB_MATH_INSTANTIATE(
double)
455 #if GEOGRAPHICLIB_HAVE_LONG_DOUBLE
457 GEOGRAPHICLIB_MATH_INSTANTIATE(
long double)
459 #if GEOGRAPHICLIB_PRECISION > 3
464 #undef GEOGRAPHICLIB_MATH_INSTANTIATE