GeographicLib 1.52
Loading...
Searching...
No Matches
Math.hpp
Go to the documentation of this file.
1/**
2 * \file Math.hpp
3 * \brief Header for GeographicLib::Math class
4 *
5 * Copyright (c) Charles Karney (2008-2020) <charles@karney.com> and licensed
6 * under the MIT/X11 License. For more information, see
7 * https://geographiclib.sourceforge.io/
8 **********************************************************************/
9
10// Constants.hpp includes Math.hpp. Place this include outside Math.hpp's
11// include guard to enforce this ordering.
13
14#if !defined(GEOGRAPHICLIB_MATH_HPP)
15#define GEOGRAPHICLIB_MATH_HPP 1
16
17#if !defined(GEOGRAPHICLIB_WORDS_BIGENDIAN)
18# define GEOGRAPHICLIB_WORDS_BIGENDIAN 0
19#endif
20
21#if !defined(GEOGRAPHICLIB_HAVE_LONG_DOUBLE)
22# define GEOGRAPHICLIB_HAVE_LONG_DOUBLE 0
23#endif
24
25#if !defined(GEOGRAPHICLIB_PRECISION)
26/**
27 * The precision of floating point numbers used in %GeographicLib. 1 means
28 * float (single precision); 2 (the default) means double; 3 means long double;
29 * 4 is reserved for quadruple precision. Nearly all the testing has been
30 * carried out with doubles and that's the recommended configuration. In order
31 * for long double to be used, GEOGRAPHICLIB_HAVE_LONG_DOUBLE needs to be
32 * defined. Note that with Microsoft Visual Studio, long double is the same as
33 * double.
34 **********************************************************************/
35# define GEOGRAPHICLIB_PRECISION 2
36#endif
37
38#include <cmath>
39#include <algorithm>
40#include <limits>
41
42#if GEOGRAPHICLIB_PRECISION == 4
43#include <boost/version.hpp>
44#include <boost/multiprecision/float128.hpp>
45#include <boost/math/special_functions.hpp>
46#elif GEOGRAPHICLIB_PRECISION == 5
47#include <mpreal.h>
48#endif
49
50#if GEOGRAPHICLIB_PRECISION > 3
51// volatile keyword makes no sense for multiprec types
52#define GEOGRAPHICLIB_VOLATILE
53// Signal a convergence failure with multiprec types by throwing an exception
54// at loop exit.
55#define GEOGRAPHICLIB_PANIC \
56 (throw GeographicLib::GeographicErr("Convergence failure"), false)
57#else
58#define GEOGRAPHICLIB_VOLATILE volatile
59// Ignore convergence failures with standard floating points types by allowing
60// loop to exit cleanly.
61#define GEOGRAPHICLIB_PANIC false
62#endif
63
64namespace GeographicLib {
65
66 /**
67 * \brief Mathematical functions needed by %GeographicLib
68 *
69 * Define mathematical functions in order to localize system dependencies and
70 * to provide generic versions of the functions. In addition define a real
71 * type to be used by %GeographicLib.
72 *
73 * Example of use:
74 * \include example-Math.cpp
75 **********************************************************************/
77 private:
78 void dummy(); // Static check for GEOGRAPHICLIB_PRECISION
79 Math(); // Disable constructor
80 public:
81
82#if GEOGRAPHICLIB_HAVE_LONG_DOUBLE
83 /**
84 * The extended precision type for real numbers, used for some testing.
85 * This is long double on computers with this type; otherwise it is double.
86 **********************************************************************/
87 typedef long double extended;
88#else
89 typedef double extended;
90#endif
91
92#if GEOGRAPHICLIB_PRECISION == 2
93 /**
94 * The real type for %GeographicLib. Nearly all the testing has been done
95 * with \e real = double. However, the algorithms should also work with
96 * float and long double (where available). (<b>CAUTION</b>: reasonable
97 * accuracy typically cannot be obtained using floats.)
98 **********************************************************************/
99 typedef double real;
100#elif GEOGRAPHICLIB_PRECISION == 1
101 typedef float real;
102#elif GEOGRAPHICLIB_PRECISION == 3
103 typedef extended real;
104#elif GEOGRAPHICLIB_PRECISION == 4
105 typedef boost::multiprecision::float128 real;
106#elif GEOGRAPHICLIB_PRECISION == 5
107 typedef mpfr::mpreal real;
108#else
109 typedef double real;
110#endif
111
112 /**
113 * @return the number of bits of precision in a real number.
114 **********************************************************************/
115 static int digits();
116
117 /**
118 * Set the binary precision of a real number.
119 *
120 * @param[in] ndigits the number of bits of precision.
121 * @return the resulting number of bits of precision.
122 *
123 * This only has an effect when GEOGRAPHICLIB_PRECISION = 5. See also
124 * Utility::set_digits for caveats about when this routine should be
125 * called.
126 **********************************************************************/
127 static int set_digits(int ndigits);
128
129 /**
130 * @return the number of decimal digits of precision in a real number.
131 **********************************************************************/
132 static int digits10();
133
134 /**
135 * Number of additional decimal digits of precision for real relative to
136 * double (0 for float).
137 **********************************************************************/
138 static int extra_digits();
139
140 /**
141 * true if the machine is big-endian.
142 **********************************************************************/
143 static const bool bigendian = GEOGRAPHICLIB_WORDS_BIGENDIAN;
144
145 /**
146 * @tparam T the type of the returned value.
147 * @return &pi;.
148 **********************************************************************/
149 template<typename T = real> static T pi() {
150 using std::atan2;
151 static const T pi = atan2(T(0), T(-1));
152 return pi;
153 }
154
155 /**
156 * @tparam T the type of the returned value.
157 * @return the number of radians in a degree.
158 **********************************************************************/
159 template<typename T = real> static T degree() {
160 static const T degree = pi<T>() / 180;
161 return degree;
162 }
163
164 /**
165 * Square a number.
166 *
167 * @tparam T the type of the argument and the returned value.
168 * @param[in] x
169 * @return <i>x</i><sup>2</sup>.
170 **********************************************************************/
171 template<typename T> static T sq(T x)
172 { return x * x; }
173
174 /**
175 * The hypotenuse function avoiding underflow and overflow.
176 *
177 * @tparam T the type of the arguments and the returned value.
178 * @param[in] x
179 * @param[in] y
180 * @return sqrt(<i>x</i><sup>2</sup> + <i>y</i><sup>2</sup>).
181 *
182 * \deprecated Use std::hypot(x, y).
183 **********************************************************************/
184 template<typename T>
185 GEOGRAPHICLIB_DEPRECATED("Use std::hypot(x, y)")
186 static T hypot(T x, T y);
187
188 /**
189 * exp(\e x) &minus; 1 accurate near \e x = 0.
190 *
191 * @tparam T the type of the argument and the returned value.
192 * @param[in] x
193 * @return exp(\e x) &minus; 1.
194 *
195 * \deprecated Use std::expm1(x).
196 **********************************************************************/
197 template<typename T>
198 GEOGRAPHICLIB_DEPRECATED("Use std::expm1(x)")
199 static T expm1(T x);
200
201 /**
202 * log(1 + \e x) accurate near \e x = 0.
203 *
204 * @tparam T the type of the argument and the returned value.
205 * @param[in] x
206 * @return log(1 + \e x).
207 *
208 * \deprecated Use std::log1p(x).
209 **********************************************************************/
210 template<typename T>
211 GEOGRAPHICLIB_DEPRECATED("Use std::log1p(x)")
212 static T log1p(T x);
213
214 /**
215 * The inverse hyperbolic sine function.
216 *
217 * @tparam T the type of the argument and the returned value.
218 * @param[in] x
219 * @return asinh(\e x).
220 *
221 * \deprecated Use std::asinh(x).
222 **********************************************************************/
223 template<typename T>
224 GEOGRAPHICLIB_DEPRECATED("Use std::asinh(x)")
225 static T asinh(T x);
226
227 /**
228 * The inverse hyperbolic tangent function.
229 *
230 * @tparam T the type of the argument and the returned value.
231 * @param[in] x
232 * @return atanh(\e x).
233 *
234 * \deprecated Use std::atanh(x).
235 **********************************************************************/
236 template<typename T>
237 GEOGRAPHICLIB_DEPRECATED("Use std::atanh(x)")
238 static T atanh(T x);
239
240 /**
241 * Copy the sign.
242 *
243 * @tparam T the type of the argument.
244 * @param[in] x gives the magitude of the result.
245 * @param[in] y gives the sign of the result.
246 * @return value with the magnitude of \e x and with the sign of \e y.
247 *
248 * This routine correctly handles the case \e y = &minus;0, returning
249 * &minus|<i>x</i>|.
250 *
251 * \deprecated Use std::copysign(x, y).
252 **********************************************************************/
253 template<typename T>
254 GEOGRAPHICLIB_DEPRECATED("Use std::copysign(x, y)")
255 static T copysign(T x, T y);
256
257 /**
258 * The cube root function.
259 *
260 * @tparam T the type of the argument and the returned value.
261 * @param[in] x
262 * @return the real cube root of \e x.
263 *
264 * \deprecated Use std::cbrt(x).
265 **********************************************************************/
266 template<typename T>
267 GEOGRAPHICLIB_DEPRECATED("Use std::cbrt(x)")
268 static T cbrt(T x);
269
270 /**
271 * The remainder function.
272 *
273 * @tparam T the type of the arguments and the returned value.
274 * @param[in] x
275 * @param[in] y
276 * @return the remainder of \e x/\e y in the range [&minus;\e y/2, \e y/2].
277 *
278 * \deprecated Use std::remainder(x).
279 **********************************************************************/
280 template<typename T>
281 GEOGRAPHICLIB_DEPRECATED("Use std::remainder(x)")
282 static T remainder(T x, T y);
283
284 /**
285 * The remquo function.
286 *
287 * @tparam T the type of the arguments and the returned value.
288 * @param[in] x
289 * @param[in] y
290 * @param[out] n the low 3 bits of the quotient
291 * @return the remainder of \e x/\e y in the range [&minus;\e y/2, \e y/2].
292 *
293 * \deprecated Use std::remquo(x, y, n).
294 **********************************************************************/
295 template<typename T>
296 GEOGRAPHICLIB_DEPRECATED("Use std::remquo(x, y, n)")
297 static T remquo(T x, T y, int* n);
298
299 /**
300 * The round function.
301 *
302 * @tparam T the type of the argument and the returned value.
303 * @param[in] x
304 * @return \e x round to the nearest integer (ties round away from 0).
305 *
306 * \deprecated Use std::round(x).
307 **********************************************************************/
308 template<typename T>
309 GEOGRAPHICLIB_DEPRECATED("Use std::round(x)")
310 static T round(T x);
311
312 /**
313 * The lround function.
314 *
315 * @tparam T the type of the argument.
316 * @param[in] x
317 * @return \e x round to the nearest integer as a long int (ties round away
318 * from 0).
319 *
320 * If the result does not fit in a long int, the return value is undefined.
321 *
322 * \deprecated Use std::lround(x).
323 **********************************************************************/
324 template<typename T>
325 GEOGRAPHICLIB_DEPRECATED("Use std::lround(x)")
326 static long lround(T x);
327
328 /**
329 * Fused multiply and add.
330 *
331 * @tparam T the type of the arguments and the returned value.
332 * @param[in] x
333 * @param[in] y
334 * @param[in] z
335 * @return <i>xy</i> + <i>z</i>, correctly rounded (on those platforms with
336 * support for the <code>fma</code> instruction).
337 *
338 * On platforms without the <code>fma</code> instruction, no attempt is
339 * made to improve on the result of a rounded multiplication followed by a
340 * rounded addition.
341 *
342 * \deprecated Use std::fma(x, y, z).
343 **********************************************************************/
344 template<typename T>
345 GEOGRAPHICLIB_DEPRECATED("Use std::fma(x, y, z)")
346 static T fma(T x, T y, T z);
347
348 /**
349 * Normalize a two-vector.
350 *
351 * @tparam T the type of the argument and the returned value.
352 * @param[in,out] x on output set to <i>x</i>/hypot(<i>x</i>, <i>y</i>).
353 * @param[in,out] y on output set to <i>y</i>/hypot(<i>x</i>, <i>y</i>).
354 **********************************************************************/
355 template<typename T> static void norm(T& x, T& y) {
356#if defined(_MSC_VER) && defined(_M_IX86)
357 // hypot for Visual Studio (A=win32) fails monotonicity, e.g., with
358 // x = 0.6102683302836215
359 // y1 = 0.7906090004346522
360 // y2 = y1 + 1e-16
361 // the test
362 // hypot(x, y2) >= hypot(x, y1)
363 // fails. Reported 2021-03-14:
364 // https://developercommunity.visualstudio.com/t/1369259
365 // See also:
366 // https://bugs.python.org/issue43088
367 using std::sqrt; T h = sqrt(x * x + y * y);
368#else
369 using std::hypot; T h = hypot(x, y);
370#endif
371 x /= h; y /= h;
372 }
373
374 /**
375 * The error-free sum of two numbers.
376 *
377 * @tparam T the type of the argument and the returned value.
378 * @param[in] u
379 * @param[in] v
380 * @param[out] t the exact error given by (\e u + \e v) - \e s.
381 * @return \e s = round(\e u + \e v).
382 *
383 * See D. E. Knuth, TAOCP, Vol 2, 4.2.2, Theorem B. (Note that \e t can be
384 * the same as one of the first two arguments.)
385 **********************************************************************/
386 template<typename T> static T sum(T u, T v, T& t);
387
388 /**
389 * Evaluate a polynomial.
390 *
391 * @tparam T the type of the arguments and returned value.
392 * @param[in] N the order of the polynomial.
393 * @param[in] p the coefficient array (of size \e N + 1).
394 * @param[in] x the variable.
395 * @return the value of the polynomial.
396 *
397 * Evaluate <i>y</i> = &sum;<sub><i>n</i>=0..<i>N</i></sub>
398 * <i>p</i><sub><i>n</i></sub> <i>x</i><sup><i>N</i>&minus;<i>n</i></sup>.
399 * Return 0 if \e N &lt; 0. Return <i>p</i><sub>0</sub>, if \e N = 0 (even
400 * if \e x is infinite or a nan). The evaluation uses Horner's method.
401 **********************************************************************/
402 template<typename T> static T polyval(int N, const T p[], T x) {
403 // This used to employ Math::fma; but that's too slow and it seemed not to
404 // improve the accuracy noticeably. This might change when there's direct
405 // hardware support for fma.
406 T y = N < 0 ? 0 : *p++;
407 while (--N >= 0) y = y * x + *p++;
408 return y;
409 }
410
411 /**
412 * Normalize an angle.
413 *
414 * @tparam T the type of the argument and returned value.
415 * @param[in] x the angle in degrees.
416 * @return the angle reduced to the range (&minus;180&deg;, 180&deg;].
417 *
418 * The range of \e x is unrestricted.
419 **********************************************************************/
420 template<typename T> static T AngNormalize(T x) {
421 using std::remainder;
422 x = remainder(x, T(360)); return x != -180 ? x : 180;
423 }
424
425 /**
426 * Normalize a latitude.
427 *
428 * @tparam T the type of the argument and returned value.
429 * @param[in] x the angle in degrees.
430 * @return x if it is in the range [&minus;90&deg;, 90&deg;], otherwise
431 * return NaN.
432 **********************************************************************/
433 template<typename T> static T LatFix(T x)
434 { using std::abs; return abs(x) > 90 ? NaN<T>() : x; }
435
436 /**
437 * The exact difference of two angles reduced to
438 * (&minus;180&deg;, 180&deg;].
439 *
440 * @tparam T the type of the arguments and returned value.
441 * @param[in] x the first angle in degrees.
442 * @param[in] y the second angle in degrees.
443 * @param[out] e the error term in degrees.
444 * @return \e d, the truncated value of \e y &minus; \e x.
445 *
446 * This computes \e z = \e y &minus; \e x exactly, reduced to
447 * (&minus;180&deg;, 180&deg;]; and then sets \e z = \e d + \e e where \e d
448 * is the nearest representable number to \e z and \e e is the truncation
449 * error. If \e d = &minus;180, then \e e &gt; 0; If \e d = 180, then \e e
450 * &le; 0.
451 **********************************************************************/
452 template<typename T> static T AngDiff(T x, T y, T& e) {
453 using std::remainder;
454 T t, d = AngNormalize(sum(remainder(-x, T(360)),
455 remainder( y, T(360)), t));
456 // Here y - x = d + t (mod 360), exactly, where d is in (-180,180] and
457 // abs(t) <= eps (eps = 2^-45 for doubles). The only case where the
458 // addition of t takes the result outside the range (-180,180] is d = 180
459 // and t > 0. The case, d = -180 + eps, t = -eps, can't happen, since
460 // sum would have returned the exact result in such a case (i.e., given t
461 // = 0).
462 return sum(d == 180 && t > 0 ? -180 : d, t, e);
463 }
464
465 /**
466 * Difference of two angles reduced to [&minus;180&deg;, 180&deg;]
467 *
468 * @tparam T the type of the arguments and returned value.
469 * @param[in] x the first angle in degrees.
470 * @param[in] y the second angle in degrees.
471 * @return \e y &minus; \e x, reduced to the range [&minus;180&deg;,
472 * 180&deg;].
473 *
474 * The result is equivalent to computing the difference exactly, reducing
475 * it to (&minus;180&deg;, 180&deg;] and rounding the result. Note that
476 * this prescription allows &minus;180&deg; to be returned (e.g., if \e x
477 * is tiny and negative and \e y = 180&deg;).
478 **********************************************************************/
479 template<typename T> static T AngDiff(T x, T y)
480 { T e; return AngDiff(x, y, e); }
481
482 /**
483 * Coarsen a value close to zero.
484 *
485 * @tparam T the type of the argument and returned value.
486 * @param[in] x
487 * @return the coarsened value.
488 *
489 * The makes the smallest gap in \e x = 1/16 &minus; nextafter(1/16, 0) =
490 * 1/2<sup>57</sup> for reals = 0.7 pm on the earth if \e x is an angle in
491 * degrees. (This is about 1000 times more resolution than we get with
492 * angles around 90&deg;.) We use this to avoid having to deal with near
493 * singular cases when \e x is non-zero but tiny (e.g.,
494 * 10<sup>&minus;200</sup>). This converts &minus;0 to +0; however tiny
495 * negative numbers get converted to &minus;0.
496 **********************************************************************/
497 template<typename T> static T AngRound(T x);
498
499 /**
500 * Evaluate the sine and cosine function with the argument in degrees
501 *
502 * @tparam T the type of the arguments.
503 * @param[in] x in degrees.
504 * @param[out] sinx sin(<i>x</i>).
505 * @param[out] cosx cos(<i>x</i>).
506 *
507 * The results obey exactly the elementary properties of the trigonometric
508 * functions, e.g., sin 9&deg; = cos 81&deg; = &minus; sin 123456789&deg;.
509 * If x = &minus;0, then \e sinx = &minus;0; this is the only case where
510 * &minus;0 is returned.
511 **********************************************************************/
512 template<typename T> static void sincosd(T x, T& sinx, T& cosx);
513
514 /**
515 * Evaluate the sine function with the argument in degrees
516 *
517 * @tparam T the type of the argument and the returned value.
518 * @param[in] x in degrees.
519 * @return sin(<i>x</i>).
520 **********************************************************************/
521 template<typename T> static T sind(T x);
522
523 /**
524 * Evaluate the cosine function with the argument in degrees
525 *
526 * @tparam T the type of the argument and the returned value.
527 * @param[in] x in degrees.
528 * @return cos(<i>x</i>).
529 **********************************************************************/
530 template<typename T> static T cosd(T x);
531
532 /**
533 * Evaluate the tangent function with the argument in degrees
534 *
535 * @tparam T the type of the argument and the returned value.
536 * @param[in] x in degrees.
537 * @return tan(<i>x</i>).
538 *
539 * If \e x = &plusmn;90&deg;, then a suitably large (but finite) value is
540 * returned.
541 **********************************************************************/
542 template<typename T> static T tand(T x);
543
544 /**
545 * Evaluate the atan2 function with the result in degrees
546 *
547 * @tparam T the type of the arguments and the returned value.
548 * @param[in] y
549 * @param[in] x
550 * @return atan2(<i>y</i>, <i>x</i>) in degrees.
551 *
552 * The result is in the range (&minus;180&deg; 180&deg;]. N.B.,
553 * atan2d(&plusmn;0, &minus;1) = +180&deg;; atan2d(&minus;&epsilon;,
554 * &minus;1) = &minus;180&deg;, for &epsilon; positive and tiny;
555 * atan2d(&plusmn;0, +1) = &plusmn;0&deg;.
556 **********************************************************************/
557 template<typename T> static T atan2d(T y, T x);
558
559 /**
560 * Evaluate the atan function with the result in degrees
561 *
562 * @tparam T the type of the argument and the returned value.
563 * @param[in] x
564 * @return atan(<i>x</i>) in degrees.
565 **********************************************************************/
566 template<typename T> static T atand(T x);
567
568 /**
569 * Evaluate <i>e</i> atanh(<i>e x</i>)
570 *
571 * @tparam T the type of the argument and the returned value.
572 * @param[in] x
573 * @param[in] es the signed eccentricity = sign(<i>e</i><sup>2</sup>)
574 * sqrt(|<i>e</i><sup>2</sup>|)
575 * @return <i>e</i> atanh(<i>e x</i>)
576 *
577 * If <i>e</i><sup>2</sup> is negative (<i>e</i> is imaginary), the
578 * expression is evaluated in terms of atan.
579 **********************************************************************/
580 template<typename T> static T eatanhe(T x, T es);
581
582 /**
583 * tan&chi; in terms of tan&phi;
584 *
585 * @tparam T the type of the argument and the returned value.
586 * @param[in] tau &tau; = tan&phi;
587 * @param[in] es the signed eccentricity = sign(<i>e</i><sup>2</sup>)
588 * sqrt(|<i>e</i><sup>2</sup>|)
589 * @return &tau;&prime; = tan&chi;
590 *
591 * See Eqs. (7--9) of
592 * C. F. F. Karney,
593 * <a href="https://doi.org/10.1007/s00190-011-0445-3">
594 * Transverse Mercator with an accuracy of a few nanometers,</a>
595 * J. Geodesy 85(8), 475--485 (Aug. 2011)
596 * (preprint
597 * <a href="https://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>).
598 **********************************************************************/
599 template<typename T> static T taupf(T tau, T es);
600
601 /**
602 * tan&phi; in terms of tan&chi;
603 *
604 * @tparam T the type of the argument and the returned value.
605 * @param[in] taup &tau;&prime; = tan&chi;
606 * @param[in] es the signed eccentricity = sign(<i>e</i><sup>2</sup>)
607 * sqrt(|<i>e</i><sup>2</sup>|)
608 * @return &tau; = tan&phi;
609 *
610 * See Eqs. (19--21) of
611 * C. F. F. Karney,
612 * <a href="https://doi.org/10.1007/s00190-011-0445-3">
613 * Transverse Mercator with an accuracy of a few nanometers,</a>
614 * J. Geodesy 85(8), 475--485 (Aug. 2011)
615 * (preprint
616 * <a href="https://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>).
617 **********************************************************************/
618 template<typename T> static T tauf(T taup, T es);
619
620 /**
621 * Test for finiteness.
622 *
623 * @tparam T the type of the argument.
624 * @param[in] x
625 * @return true if number is finite, false if NaN or infinite.
626 *
627 * \deprecated Use std::isfinite(x).
628 **********************************************************************/
629 template<typename T>
630 GEOGRAPHICLIB_DEPRECATED("Use std::isfinite(x)")
631 static bool isfinite(T x);
632
633 /**
634 * The NaN (not a number)
635 *
636 * @tparam T the type of the returned value.
637 * @return NaN if available, otherwise return the max real of type T.
638 **********************************************************************/
639 template<typename T = real> static T NaN();
640
641 /**
642 * Test for NaN.
643 *
644 * @tparam T the type of the argument.
645 * @param[in] x
646 * @return true if argument is a NaN.
647 *
648 * \deprecated Use std::isnan(x).
649 **********************************************************************/
650 template<typename T>
651 GEOGRAPHICLIB_DEPRECATED("Use std::isnan(x)")
652 static bool isnan(T x);
653
654 /**
655 * Infinity
656 *
657 * @tparam T the type of the returned value.
658 * @return infinity if available, otherwise return the max real.
659 **********************************************************************/
660 template<typename T = real> static T infinity();
661
662 /**
663 * Swap the bytes of a quantity
664 *
665 * @tparam T the type of the argument and the returned value.
666 * @param[in] x
667 * @return x with its bytes swapped.
668 **********************************************************************/
669 template<typename T> static T swab(T x) {
670 union {
671 T r;
672 unsigned char c[sizeof(T)];
673 } b;
674 b.r = x;
675 for (int i = sizeof(T)/2; i--; )
676 std::swap(b.c[i], b.c[sizeof(T) - 1 - i]);
677 return b.r;
678 }
679
680 };
681
682} // namespace GeographicLib
683
684#endif // GEOGRAPHICLIB_MATH_HPP
Header for GeographicLib::Constants class.
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:66
#define GEOGRAPHICLIB_DEPRECATED(msg)
Definition: Constants.hpp:81
GeographicLib::Math::real real
Definition: GeodSolve.cpp:31
#define GEOGRAPHICLIB_WORDS_BIGENDIAN
Definition: Math.hpp:18
Mathematical functions needed by GeographicLib.
Definition: Math.hpp:76
static T AngNormalize(T x)
Definition: Math.hpp:420
static T degree()
Definition: Math.hpp:159
static T LatFix(T x)
Definition: Math.hpp:433
double extended
Definition: Math.hpp:89
static T sq(T x)
Definition: Math.hpp:171
static T pi()
Definition: Math.hpp:149
static T polyval(int N, const T p[], T x)
Definition: Math.hpp:402
static T AngDiff(T x, T y)
Definition: Math.hpp:479
static T AngDiff(T x, T y, T &e)
Definition: Math.hpp:452
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
void swap(GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &a, GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &b)