Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #if !defined(GEOGRAPHICLIB_CONSTANTS_HPP)
00011 #define GEOGRAPHICLIB_CONSTANTS_HPP "$Id: Constants.hpp 6967 2011-02-19 15:53:41Z karney $"
00012
00013
00014
00015
00016 #if !defined(GEOGRAPHICLIB_CPLUSPLUS0X_MATH)
00017 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00018 #define GEOGRAPHICLIB_CPLUSPLUS0X_MATH 1
00019 #else
00020 #define GEOGRAPHICLIB_CPLUSPLUS0X_MATH 0
00021 #endif
00022 #endif
00023
00024
00025
00026
00027 #if !defined(STATIC_ASSERT)
00028 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00029 #define STATIC_ASSERT static_assert
00030 #elif defined(_MSC_VER) && _MSC_VER >= 1600
00031 #define STATIC_ASSERT static_assert
00032 #else
00033 #define STATIC_ASSERT(cond,reason) { enum{ STATIC_ASSERT_ENUM=1/int(cond) }; }
00034 #endif
00035 #endif
00036
00037 #if defined(__GNUC__)
00038
00039 #define RCSID_DECL(x) namespace \
00040 { char VAR_ ## x [] __attribute__((used)) = x; }
00041 #else
00042
00043
00044
00045 #define RCSID_DECL(x) namespace { char VAR_ ## x [] = x; }
00046 #endif
00047
00048 RCSID_DECL(GEOGRAPHICLIB_CONSTANTS_HPP)
00049
00050 #if !defined(GEOGRAPHICLIB_PREC)
00051
00052
00053
00054
00055
00056
00057
00058 #define GEOGRAPHICLIB_PREC 1
00059 #endif
00060
00061 #if defined(__CYGWIN__) && defined(__GNUC__) && __GNUC__ < 4
00062
00063 #define __NO_LONG_DOUBLE_MATH 1
00064 #endif
00065
00066 #include <cmath>
00067 #include <limits>
00068 #include <algorithm>
00069 #include <stdexcept>
00070
00071
00072
00073
00074
00075
00076
00077
00078 namespace GeographicLib {
00079
00080
00081
00082
00083
00084
00085
00086
00087 class Math {
00088 private:
00089 void dummy() {
00090 STATIC_ASSERT((GEOGRAPHICLIB_PREC) >= 0 && (GEOGRAPHICLIB_PREC) <= 2,
00091 "Bad value of precision");
00092 }
00093 Math();
00094 public:
00095
00096 #if !defined(__NO_LONG_DOUBLE_MATH)
00097
00098
00099
00100
00101 typedef long double extended;
00102 #else
00103 typedef double extended;
00104 #endif
00105
00106 #if GEOGRAPHICLIB_PREC == 1
00107
00108
00109
00110
00111
00112 typedef double real;
00113 #elif GEOGRAPHICLIB_PREC == 0
00114 typedef float real;
00115 #elif GEOGRAPHICLIB_PREC == 2
00116 typedef extended real;
00117 #else
00118 typedef double real;
00119 #endif
00120
00121
00122
00123
00124 template<typename T>
00125 static inline T pi() throw()
00126
00127 { return T(3.1415926535897932384626433832795028841971693993751L); }
00128
00129
00130
00131 static inline real pi() throw() { return pi<real>(); }
00132
00133
00134
00135 static inline extended epi() throw() { return pi<extended>(); }
00136
00137
00138
00139
00140 template<typename T>
00141 static inline T degree() throw() { return pi<T>() / T(180); }
00142
00143
00144
00145 static inline real degree() throw() { return degree<real>(); }
00146
00147
00148
00149 static inline extended edegree() throw() { return degree<extended>(); }
00150
00151 #if defined(DOXYGEN)
00152
00153
00154
00155
00156
00157
00158
00159 template<typename T>
00160 static inline T hypot(T x, T y) throw() {
00161 x = std::abs(x);
00162 y = std::abs(y);
00163 T a = std::max(x, y),
00164 b = std::min(x, y) / a;
00165 return a * std::sqrt(1 + b * b);
00166 }
00167 #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH
00168 template<typename T>
00169 static inline T hypot(T x, T y) throw() { return std::hypot(x, y); }
00170 #elif defined(_MSC_VER)
00171 static inline double hypot(double x, double y) throw()
00172 { return _hypot(x, y); }
00173 static inline float hypot(float x, float y) throw()
00174 { return _hypotf(x, y); }
00175 #if !defined(__NO_LONG_DOUBLE_MATH)
00176 static inline long double hypot(long double x, long double y) throw()
00177 { return _hypot(x, y); }
00178 #endif
00179 #else
00180
00181 static inline double hypot(double x, double y) throw()
00182 { return ::hypot(x, y); }
00183 static inline float hypot(float x, float y) throw()
00184 { return ::hypotf(x, y); }
00185 #if !defined(__NO_LONG_DOUBLE_MATH)
00186 static inline long double hypot(long double x, long double y) throw()
00187 { return ::hypotl(x, y); }
00188 #endif
00189 #endif
00190
00191 #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MATH)
00192
00193
00194
00195
00196
00197
00198
00199
00200 template<typename T>
00201 static inline T expm1(T x) throw() {
00202 volatile T
00203 y = std::exp(x),
00204 z = y - 1;
00205
00206
00207
00208
00209 return std::abs(x) > 1 ? z : z == 0 ? x : x * z / std::log(y);
00210 }
00211 #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH
00212 template<typename T>
00213 static inline T expm1(T x) throw() { return std::expm1(x); }
00214 #else
00215 static inline double expm1(double x) throw() { return ::expm1(x); }
00216 static inline float expm1(float x) throw() { return ::expm1f(x); }
00217 #if !defined(__NO_LONG_DOUBLE_MATH)
00218 static inline long double expm1(long double x) throw()
00219 { return ::expm1l(x); }
00220 #endif
00221 #endif
00222
00223 #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MATH)
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 template<typename T>
00236 static inline T log1p(T x) throw() {
00237 volatile T
00238 y = 1 + x,
00239 z = y - 1;
00240
00241
00242
00243
00244 return z == 0 ? x : x * std::log(y) / z;
00245 }
00246 #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH
00247 template<typename T>
00248 static inline T log1p(T x) throw() { return std::log1p(x); }
00249 #else
00250 static inline double log1p(double x) throw() { return ::log1p(x); }
00251 static inline float log1p(float x) throw() { return ::log1pf(x); }
00252 #if !defined(__NO_LONG_DOUBLE_MATH)
00253 static inline long double log1p(long double x) throw()
00254 { return ::log1pl(x); }
00255 #endif
00256 #endif
00257
00258 #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MATH)
00259
00260
00261
00262
00263
00264
00265
00266
00267 template<typename T>
00268 static inline T asinh(T x) throw() {
00269 T y = std::abs(x);
00270 y = log1p(y * (1 + y/(hypot(T(1), y) + 1)));
00271 return x < 0 ? -y : y;
00272 }
00273 #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH
00274 template<typename T>
00275 static inline T asinh(T x) throw() { return std::asinh(x); }
00276 #else
00277 static inline double asinh(double x) throw() { return ::asinh(x); }
00278 static inline float asinh(float x) throw() { return ::asinhf(x); }
00279 #if !defined(__NO_LONG_DOUBLE_MATH)
00280 static inline long double asinh(long double x) throw()
00281 { return ::asinhl(x); }
00282 #endif
00283 #endif
00284
00285 #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MATH)
00286
00287
00288
00289
00290
00291
00292
00293
00294 template<typename T>
00295 static inline T atanh(T x) throw() {
00296 T y = std::abs(x);
00297 y = log1p(2 * y/(1 - y))/2;
00298 return x < 0 ? -y : y;
00299 }
00300 #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH
00301 template<typename T>
00302 static inline T atanh(T x) throw() { return std::atanh(x); }
00303 #else
00304 static inline double atanh(double x) throw() { return ::atanh(x); }
00305 static inline float atanh(float x) throw() { return ::atanhf(x); }
00306 #if !defined(__NO_LONG_DOUBLE_MATH)
00307 static inline long double atanh(long double x) throw()
00308 { return ::atanhl(x); }
00309 #endif
00310 #endif
00311
00312 #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MATH)
00313
00314
00315
00316
00317
00318
00319 template<typename T>
00320 static inline T cbrt(T x) throw() {
00321 T y = std::pow(std::abs(x), 1/T(3));
00322 return x < 0 ? -y : y;
00323 }
00324 #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH
00325 template<typename T>
00326 static inline T cbrt(T x) throw() { return std::cbrt(x); }
00327 #else
00328 static inline double cbrt(double x) throw() { return ::cbrt(x); }
00329 static inline float cbrt(float x) throw() { return ::cbrtf(x); }
00330 #if !defined(__NO_LONG_DOUBLE_MATH)
00331 static inline long double cbrt(long double x) throw() { return ::cbrtl(x); }
00332 #endif
00333 #endif
00334
00335
00336
00337
00338
00339
00340
00341 template<typename T>
00342 static inline bool isfinite(T x) throw() {
00343 #if defined(DOXYGEN)
00344 return std::abs(x) <= std::numeric_limits<T>::max();
00345 #elif (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MATH)
00346 return _finite(x) != 0;
00347 #else
00348 return std::isfinite(x);
00349 #endif
00350 }
00351
00352
00353
00354
00355
00356
00357 template<typename T>
00358 static inline T NaN() throw() {
00359 return std::numeric_limits<T>::has_quiet_NaN ?
00360 std::numeric_limits<T>::quiet_NaN() :
00361 std::numeric_limits<T>::max();
00362 }
00363
00364
00365
00366 static inline real NaN() throw() { return NaN<real>(); }
00367
00368
00369
00370
00371
00372
00373
00374 template<typename T>
00375 static inline bool isnan(T x) throw() {
00376 #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MATH)
00377 return x != x;
00378 #else
00379 return std::isnan(x);
00380 #endif
00381 }
00382
00383
00384
00385
00386
00387
00388 template<typename T>
00389 static inline T infinity() throw() {
00390 return std::numeric_limits<T>::has_infinity ?
00391 std::numeric_limits<T>::infinity() :
00392 std::numeric_limits<T>::max();
00393 }
00394
00395
00396
00397 static inline real infinity() throw() { return infinity<real>(); }
00398 };
00399
00400
00401
00402
00403
00404
00405
00406 class Constants {
00407 private:
00408 typedef Math::real real;
00409 Constants();
00410
00411 public:
00412
00413
00414
00415 static inline Math::real pi() throw() { return Math::pi<real>(); }
00416
00417
00418
00419 static inline Math::real degree() throw() { return Math::degree<real>(); }
00420
00421
00422
00423 static inline Math::real arcminute() throw()
00424 { return Math::degree<real>() / 60; }
00425
00426
00427
00428 static inline Math::real arcsecond() throw()
00429 { return Math::degree<real>() / 3600; }
00430
00431
00432
00433
00434
00435
00436
00437 template<typename T>
00438 static inline T WGS84_a() throw() { return T(6378137) * meter<T>(); }
00439
00440
00441
00442 static inline Math::real WGS84_a() throw() { return WGS84_a<real>(); }
00443
00444
00445
00446 template<typename T>
00447 static inline T WGS84_r() throw() {
00448
00449 return (T(3393) * T(87903691)) / T(1000000000);
00450 }
00451
00452
00453
00454 static inline Math::real WGS84_r() throw() { return WGS84_r<real>(); }
00455
00456
00457
00458 template<typename T>
00459 static inline T UTM_k0() throw() {return T(9996) / T(10000); }
00460
00461
00462
00463 static inline Math::real UTM_k0() throw() { return UTM_k0<real>(); }
00464
00465
00466
00467 template<typename T>
00468 static inline T UPS_k0() throw() { return T(994) / T(1000); }
00469
00470
00471
00472 static inline Math::real UPS_k0() throw() { return UPS_k0<real>(); }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 template<typename T>
00485 static inline T meter() throw() { return T(1); }
00486
00487
00488
00489 static inline Math::real meter() throw() { return meter<real>(); }
00490
00491
00492
00493 static inline Math::real kilometer() throw()
00494 { return 1000 * meter<real>(); }
00495
00496
00497
00498
00499 static inline Math::real nauticalmile() throw()
00500 { return 1852 * meter<real>(); }
00501
00502
00503
00504
00505
00506
00507
00508
00509 static inline Math::real foot() throw()
00510 { return real(0.0254L) * 12 * meter<real>(); }
00511
00512
00513
00514 static inline Math::real yard() throw() { return 3 * foot(); }
00515
00516
00517
00518 static inline Math::real fathom() throw() { return 2 * yard(); }
00519
00520
00521
00522 static inline Math::real chain() throw() { return 22 * yard(); }
00523
00524
00525
00526 static inline Math::real furlong() throw() { return 10 * chain(); }
00527
00528
00529
00530 static inline Math::real mile() throw() { return 8 * furlong(); }
00531
00532
00533
00534
00535
00536
00537
00538
00539 static inline Math::real surveyfoot() throw()
00540 { return real(1200) / real(3937) * meter<real>(); }
00541
00542 };
00543
00544
00545
00546
00547
00548
00549
00550 class GeographicErr : public std::runtime_error {
00551 public:
00552
00553
00554
00555
00556
00557
00558
00559 GeographicErr(const std::string& msg) : std::runtime_error(msg) {}
00560 };
00561
00562 }
00563
00564 #endif