aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Evers <kristianevers@gmail.com>2018-04-23 14:17:37 +0200
committerGitHub <noreply@github.com>2018-04-23 14:17:37 +0200
commit93db7b7b16f8904e23a7516079708ec82977fad3 (patch)
treea02f038f3c058ad01d5514c0d1d10a886bc2f56f
parente833dbb8d8d5df290bc76bd1d757bf36b62ecf49 (diff)
parent6f640d76e13cb643574b44b7498d51ecff6fb83e (diff)
downloadPROJ-93db7b7b16f8904e23a7516079708ec82977fad3.tar.gz
PROJ-93db7b7b16f8904e23a7516079708ec82977fad3.zip
Merge pull request #937 from kbevers/c99-math-module
Collect custom C99 math functions in proj_math.h
-rw-r--r--CMakeLists.txt3
-rw-r--r--configure.ac3
-rw-r--r--src/Makefile.am4
-rw-r--r--src/PJ_aea.c2
-rw-r--r--src/PJ_aeqd.c1
-rw-r--r--src/PJ_bipc.c1
-rw-r--r--src/PJ_bonne.c2
-rw-r--r--src/PJ_cart.c2
-rw-r--r--src/PJ_ccon.c1
-rw-r--r--src/PJ_deformation.c1
-rw-r--r--src/PJ_eqdc.c1
-rw-r--r--src/PJ_geos.c1
-rw-r--r--src/PJ_gnom.c1
-rw-r--r--src/PJ_laea.c1
-rw-r--r--src/PJ_lcc.c1
-rw-r--r--src/PJ_merc.c23
-rw-r--r--src/PJ_mod_ster.c1
-rw-r--r--src/PJ_nsper.c1
-rw-r--r--src/PJ_oea.c1
-rw-r--r--src/PJ_ortho.c1
-rw-r--r--src/PJ_robin.c5
-rw-r--r--src/PJ_sconics.c1
-rw-r--r--src/PJ_stere.c1
-rw-r--r--src/PJ_sterea.c1
-rw-r--r--src/PJ_tpeqd.c1
-rw-r--r--src/geodesic.c7
-rw-r--r--src/gie.c1
-rw-r--r--src/hypot.c36
-rw-r--r--src/lib_proj.cmake2
-rw-r--r--src/makefile.vc2
-rw-r--r--src/nad_cvt.c1
-rw-r--r--src/nad_intr.c5
-rw-r--r--src/pj_apply_vgridshift.c4
-rw-r--r--src/pj_factors.c1
-rw-r--r--src/pj_init.c1
-rw-r--r--src/pj_internal.c16
-rw-r--r--src/pj_math.c71
-rw-r--r--src/proj_4D_api.c1
-rw-r--r--src/proj_etmerc.c29
-rw-r--r--src/proj_math.h55
-rw-r--r--src/projects.h5
41 files changed, 179 insertions, 119 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6d7c4f77..d7afe060 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -96,7 +96,8 @@ int main() {
int q;
return (int)(hypot(3.0, 4.0) + atanh(0.8) + cbrt(8.0) +
remquo(100.0, 90.0, &q) +
- remainder(100.0, 90.0) + copysign(1.0, -0.0)) +
+ remainder(100.0, 90.0) + copysign(1.0, -0.0) +
+ log1p(0.1) + asinh(0.1)) +
isnan(0.0);
}\n" C99_MATH)
if (C99_MATH)
diff --git a/configure.ac b/configure.ac
index 269225a5..e89961eb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -45,7 +45,8 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM(
[int q;
return (int)(hypot(3.0, 4.0) + atanh(0.8) + cbrt(8.0) +
remquo(100.0, 90.0, &q) +
- remainder(100.0, 90.0) + copysign(1.0, -0.0)) +
+ remainder(100.0, 90.0) + copysign(1.0, -0.0) +
+ log1p(0.1) + asinh(0.1)) +
isnan(0.0);])],
[AC_MSG_RESULT([yes]);C99_MATH="-DHAVE_C99_MATH=1"],
[AC_MSG_RESULT([no]);C99_MATH="-DHAVE_C99_MATH=0"])
diff --git a/src/Makefile.am b/src/Makefile.am
index f94e5f26..78ecfdf8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -43,7 +43,7 @@ lib_LTLIBRARIES = libproj.la
libproj_la_LDFLAGS = -no-undefined -version-info 13:0:0
libproj_la_SOURCES = \
- pj_list.h proj_internal.h\
+ pj_list.h proj_internal.h proj_math.h\
PJ_aeqd.c PJ_gnom.c PJ_laea.c PJ_mod_ster.c \
PJ_nsper.c PJ_nzmg.c PJ_ortho.c PJ_stere.c PJ_sterea.c \
PJ_aea.c PJ_bipc.c PJ_bonne.c PJ_eqdc.c PJ_isea.c PJ_ccon.c\
@@ -83,7 +83,7 @@ libproj_la_SOURCES = \
pj_apply_gridshift.c pj_datums.c pj_datum_set.c pj_transform.c \
geocent.c geocent.h pj_utils.c pj_gridinfo.c pj_gridlist.c \
jniproj.c pj_mutex.c pj_initcache.c pj_apply_vgridshift.c geodesic.c \
- pj_strtod.c \
+ pj_strtod.c pj_math.c\
\
proj_4D_api.c PJ_cart.c PJ_pipeline.c PJ_horner.c PJ_helmert.c \
PJ_vgridshift.c PJ_hgridshift.c PJ_unitconvert.c PJ_molodensky.c \
diff --git a/src/PJ_aea.c b/src/PJ_aea.c
index 3fe90524..640f1013 100644
--- a/src/PJ_aea.c
+++ b/src/PJ_aea.c
@@ -31,6 +31,8 @@
#include "proj.h"
#include <errno.h>
#include "projects.h"
+#include "proj_math.h"
+
# define EPS10 1.e-10
# define TOL7 1.e-7
diff --git a/src/PJ_aeqd.c b/src/PJ_aeqd.c
index 84554b91..5d8c3d38 100644
--- a/src/PJ_aeqd.c
+++ b/src/PJ_aeqd.c
@@ -30,6 +30,7 @@
#include "proj.h"
#include <errno.h>
#include "projects.h"
+#include "proj_math.h"
enum Mode {
N_POLE = 0,
diff --git a/src/PJ_bipc.c b/src/PJ_bipc.c
index 48fc93d0..2f60808d 100644
--- a/src/PJ_bipc.c
+++ b/src/PJ_bipc.c
@@ -2,6 +2,7 @@
#include "proj.h"
#include <errno.h>
#include "projects.h"
+#include "proj_math.h"
PROJ_HEAD(bipc, "Bipolar conic of western hemisphere") "\n\tConic Sph.";
diff --git a/src/PJ_bonne.c b/src/PJ_bonne.c
index 40bb28ee..d3d5b757 100644
--- a/src/PJ_bonne.c
+++ b/src/PJ_bonne.c
@@ -2,6 +2,8 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
+
PROJ_HEAD(bonne, "Bonne (Werner lat_1=90)")
"\n\tConic Sph&Ell\n\tlat_1=";
diff --git a/src/PJ_cart.c b/src/PJ_cart.c
index ec273f1b..a4fd3254 100644
--- a/src/PJ_cart.c
+++ b/src/PJ_cart.c
@@ -43,8 +43,8 @@
#define PJ_LIB__
#include "proj_internal.h"
#include "projects.h"
+#include "proj_math.h"
#include <stddef.h>
-#include <math.h>
#include <errno.h>
PROJ_HEAD(cart, "Geodetic/cartesian conversions");
diff --git a/src/PJ_ccon.c b/src/PJ_ccon.c
index 02b14388..aed59fb6 100644
--- a/src/PJ_ccon.c
+++ b/src/PJ_ccon.c
@@ -24,6 +24,7 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
#define EPS10 1e-10
diff --git a/src/PJ_deformation.c b/src/PJ_deformation.c
index 58c0e4df..5511eed4 100644
--- a/src/PJ_deformation.c
+++ b/src/PJ_deformation.c
@@ -55,6 +55,7 @@ grid-values in units of mm/year in ENU-space.
#include <errno.h>
#include "proj.h"
#include "proj_internal.h"
+#include "proj_math.h"
#include "projects.h"
PROJ_HEAD(deformation, "Kinematic grid shift");
diff --git a/src/PJ_eqdc.c b/src/PJ_eqdc.c
index f36e0518..5f65e7d0 100644
--- a/src/PJ_eqdc.c
+++ b/src/PJ_eqdc.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
struct pj_opaque {
double phi1;
diff --git a/src/PJ_geos.c b/src/PJ_geos.c
index f0a9bc24..2988e62e 100644
--- a/src/PJ_geos.c
+++ b/src/PJ_geos.c
@@ -31,6 +31,7 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
struct pj_opaque {
double h;
diff --git a/src/PJ_gnom.c b/src/PJ_gnom.c
index 8bb24b6a..b4bab0e2 100644
--- a/src/PJ_gnom.c
+++ b/src/PJ_gnom.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
PROJ_HEAD(gnom, "Gnomonic") "\n\tAzi, Sph.";
diff --git a/src/PJ_laea.c b/src/PJ_laea.c
index 0422784b..bcf9c44d 100644
--- a/src/PJ_laea.c
+++ b/src/PJ_laea.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
PROJ_HEAD(laea, "Lambert Azimuthal Equal Area") "\n\tAzi, Sph&Ell";
diff --git a/src/PJ_lcc.c b/src/PJ_lcc.c
index 863f6be9..34ed99cb 100644
--- a/src/PJ_lcc.c
+++ b/src/PJ_lcc.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
PROJ_HEAD(lcc, "Lambert Conformal Conic")
"\n\tConic, Sph&Ell\n\tlat_1= and lat_2= or lat_0";
diff --git a/src/PJ_merc.c b/src/PJ_merc.c
index 0bf98625..9123eae1 100644
--- a/src/PJ_merc.c
+++ b/src/PJ_merc.c
@@ -1,6 +1,7 @@
#define PJ_LIB__
#include "proj_internal.h"
#include "proj.h"
+#include "proj_math.h"
#include "projects.h"
#include <float.h>
@@ -8,30 +9,10 @@ PROJ_HEAD(merc, "Mercator") "\n\tCyl, Sph&Ell\n\tlat_ts=";
PROJ_HEAD(webmerc, "Web Mercator / Pseudo Mercator") "\n\tCyl, Sph\n\t";
#define EPS10 1.e-10
-
-#if !defined(HAVE_C99_MATH)
-#define HAVE_C99_MATH 0
-#endif
-
-#if HAVE_C99_MATH
-#define log1px log1p
-#else
-static double log1px(double x) {
- volatile double
- y = 1 + x,
- z = y - 1;
- /* Here's the explanation for this magic: y = 1 + z, exactly, and z
- * approx x, thus log(y)/z (which is nearly constant near z = 0) returns
- * a good approximation to the true log(1 + x)/x. The multiplication x *
- * (log(y)/z) introduces little additional error. */
- return z == 0 ? x : x * log(y) / z;
-}
-#endif
-
static double logtanpfpim1(double x) { /* log(tan(x/2 + M_FORTPI)) */
if (fabs(x) <= DBL_EPSILON) {
/* tan(M_FORTPI + .5 * x) can be approximated by 1.0 + x */
- return log1px(x);
+ return log1p(x);
}
return log(tan(M_FORTPI + .5 * x));
}
diff --git a/src/PJ_mod_ster.c b/src/PJ_mod_ster.c
index d807660c..5e6ce136 100644
--- a/src/PJ_mod_ster.c
+++ b/src/PJ_mod_ster.c
@@ -2,6 +2,7 @@
#define PJ_LIB__
#include <errno.h>
#include "projects.h"
+#include "proj_math.h"
PROJ_HEAD(mil_os, "Miller Oblated Stereographic") "\n\tAzi(mod)";
PROJ_HEAD(lee_os, "Lee Oblated Stereographic") "\n\tAzi(mod)";
diff --git a/src/PJ_nsper.c b/src/PJ_nsper.c
index 3c0b01f0..223cd75b 100644
--- a/src/PJ_nsper.c
+++ b/src/PJ_nsper.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
enum Mode {
N_POLE = 0,
diff --git a/src/PJ_oea.c b/src/PJ_oea.c
index 5112896f..2bfeffa8 100644
--- a/src/PJ_oea.c
+++ b/src/PJ_oea.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
PROJ_HEAD(oea, "Oblated Equal Area") "\n\tMisc Sph\n\tn= m= theta=";
diff --git a/src/PJ_ortho.c b/src/PJ_ortho.c
index 7c27cd56..2b037819 100644
--- a/src/PJ_ortho.c
+++ b/src/PJ_ortho.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include "proj.h"
#include "proj_internal.h"
+#include "proj_math.h"
#include "projects.h"
PROJ_HEAD(ortho, "Orthographic") "\n\tAzi, Sph.";
diff --git a/src/PJ_robin.c b/src/PJ_robin.c
index 92aebfd3..a1d5ad4d 100644
--- a/src/PJ_robin.c
+++ b/src/PJ_robin.c
@@ -1,4 +1,5 @@
#define PJ_LIB__
+#include "proj_math.h"
#include "proj_internal.h"
#include "proj.h"
#include "projects.h"
@@ -82,7 +83,7 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
(void) P;
dphi = fabs(lp.phi);
- i = pj_is_nan(lp.phi) ? -1 : (int)floor(dphi * C1);
+ i = isnan(lp.phi) ? -1 : (int)floor(dphi * C1);
if( i < 0 ){
proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
return xy;
@@ -117,7 +118,7 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
}
} else { /* general problem */
/* in Y space, reduce to table interval */
- i = pj_is_nan(lp.phi) ? -1 : (int)floor(lp.phi * NODES);
+ i = isnan(lp.phi) ? -1 : (int)floor(lp.phi * NODES);
if( i < 0 || i >= NODES ) {
proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
return lp;
diff --git a/src/PJ_sconics.c b/src/PJ_sconics.c
index 34a0f1fd..ce044c24 100644
--- a/src/PJ_sconics.c
+++ b/src/PJ_sconics.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
enum Type {
diff --git a/src/PJ_stere.c b/src/PJ_stere.c
index 62e42460..82fd5c07 100644
--- a/src/PJ_stere.c
+++ b/src/PJ_stere.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
PROJ_HEAD(stere, "Stereographic") "\n\tAzi, Sph&Ell\n\tlat_ts=";
PROJ_HEAD(ups, "Universal Polar Stereographic") "\n\tAzi, Sph&Ell\n\tsouth";
diff --git a/src/PJ_sterea.c b/src/PJ_sterea.c
index 96b35609..eb4c9f2c 100644
--- a/src/PJ_sterea.c
+++ b/src/PJ_sterea.c
@@ -26,6 +26,7 @@
#define PJ_LIB__
#include <errno.h>
#include "projects.h"
+#include "proj_math.h"
struct pj_opaque {
diff --git a/src/PJ_tpeqd.c b/src/PJ_tpeqd.c
index 21e3c5ed..87877ec1 100644
--- a/src/PJ_tpeqd.c
+++ b/src/PJ_tpeqd.c
@@ -1,6 +1,7 @@
#define PJ_LIB__
#include <errno.h>
#include "proj.h"
+#include "proj_math.h"
#include "projects.h"
diff --git a/src/geodesic.c b/src/geodesic.c
index eb956c65..9904c7fa 100644
--- a/src/geodesic.c
+++ b/src/geodesic.c
@@ -24,7 +24,11 @@
*/
#include "geodesic.h"
+#ifdef PJ_LIB__
+#include "proj_math.h"
+#else
#include <math.h>
+#endif
#if !defined(HAVE_C99_MATH)
#define HAVE_C99_MATH 0
@@ -239,8 +243,7 @@ static void sincosdx(real x, real* sinx, real* cosx) {
r = remquo(x, (real)(90), &q);
#else
r = fmod(x, (real)(360));
- /* check for NaN -- do not use pj_is_nan, since we want geodesic.c not to
- * depend on the rest of proj.4 */
+ /* check for NaN */
q = r == r ? (int)(floor(r / 90 + (real)(0.5))) : 0;
r -= 90 * q;
#endif
diff --git a/src/gie.c b/src/gie.c
index 3831a8f1..b81e6bdc 100644
--- a/src/gie.c
+++ b/src/gie.c
@@ -114,6 +114,7 @@ Thomas Knudsen, thokn@sdfe.dk, 2017-10-01/2017-10-08
#include "proj.h"
#include "proj_internal.h"
+#include "proj_math.h"
#include "projects.h"
#include "optargpm.h"
diff --git a/src/hypot.c b/src/hypot.c
deleted file mode 100644
index 822c4595..00000000
--- a/src/hypot.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* hypot - sqrt(x * x + y * y)
-**
-** Because this was omitted from the ANSI standards, this version
-** is included for those systems that do not include hypot as an
-** extension to libm.a. Note: GNU version was not used because it
-** was not properly coded to minimize potential overflow.
-**
-** The proper technique for determining hypot is to factor out the
-** larger of the two terms, thus leaving a possible case of float
-** overflow when max(x,y)*sqrt(2) > max machine value. This allows
-** a wider range of numbers than the alternative of the sum of the
-** squares < max machine value. For an Intel x87 IEEE double of
-** approximately 1.8e308, only argument values > 1.27e308 are at
-** risk of causing overflow. Whereas, not using this method limits
-** the range to values less that 9.5e153 --- a considerable reduction
-** in range!
-*/
-extern double sqrt(double);
- double
-hypot(double x, double y) {
- if ( x < 0.)
- x = -x;
- else if (x == 0.)
- return (y < 0. ? -y : y);
- if (y < 0.)
- y = -y;
- else if (y == 0.)
- return (x);
- if ( x < y ) {
- x /= y;
- return ( y * sqrt( 1. + x * x ) );
- } else {
- y /= x;
- return ( x * sqrt( 1. + y * y ) );
- }
-}
diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake
index c9e4d9e6..c0d0a6a9 100644
--- a/src/lib_proj.cmake
+++ b/src/lib_proj.cmake
@@ -199,6 +199,7 @@ SET(SRC_LIBPROJ_CORE
pj_list.h
pj_log.c
pj_malloc.c
+ pj_math.c
pj_mlfn.c
pj_msfn.c
pj_mutex.c
@@ -218,6 +219,7 @@ SET(SRC_LIBPROJ_CORE
pj_utils.c
pj_zpoly1.c
proj_mdist.c
+ proj_math.h
proj_rouss.c
rtodms.c
vector1.c
diff --git a/src/makefile.vc b/src/makefile.vc
index ee89beb3..ef39b084 100644
--- a/src/makefile.vc
+++ b/src/makefile.vc
@@ -55,7 +55,7 @@ support = \
pj_utils.obj pj_gridlist.obj pj_gridinfo.obj \
proj_mdist.obj pj_mutex.obj pj_initcache.obj \
pj_ctx.obj pj_fileapi.obj pj_log.obj pj_apply_vgridshift.obj \
- pj_strtod.obj pj_internal.obj
+ pj_strtod.obj pj_internal.obj pj_math.obj
pipeline = \
proj_4D_api.obj PJ_cart.obj PJ_pipeline.obj PJ_horner.obj PJ_helmert.obj \
diff --git a/src/nad_cvt.c b/src/nad_cvt.c
index c913511f..d4330d54 100644
--- a/src/nad_cvt.c
+++ b/src/nad_cvt.c
@@ -1,5 +1,6 @@
#define PJ_LIB__
#include "projects.h"
+#include "proj_math.h"
#define MAX_ITERATIONS 10
#define TOL 1e-12
diff --git a/src/nad_intr.c b/src/nad_intr.c
index dc245831..80e428ed 100644
--- a/src/nad_intr.c
+++ b/src/nad_intr.c
@@ -1,6 +1,7 @@
/* Determine nad table correction value */
#define PJ_LIB__
#include "proj_internal.h"
+#include "proj_math.h"
#include "projects.h"
LP
@@ -13,9 +14,9 @@ nad_intr(LP t, struct CTABLE *ct) {
int in;
t.lam /= ct->del.lam;
- indx.lam = pj_is_nan(t.lam) ? 0 : (int)floor(t.lam);
+ indx.lam = isnan(t.lam) ? 0 : (int)floor(t.lam);
t.phi /= ct->del.phi;
- indx.phi = pj_is_nan(t.phi) ? 0 : (int)floor(t.phi);
+ indx.phi = isnan(t.phi) ? 0 : (int)floor(t.phi);
frct.lam = t.lam - indx.lam;
frct.phi = t.phi - indx.phi;
diff --git a/src/pj_apply_vgridshift.c b/src/pj_apply_vgridshift.c
index 05803bc8..e7106b25 100644
--- a/src/pj_apply_vgridshift.c
+++ b/src/pj_apply_vgridshift.c
@@ -29,7 +29,7 @@
#define PJ_LIB__
#include <string.h>
-#include <math.h>
+#include "proj_math.h"
#include "proj_internal.h"
#include "projects.h"
@@ -42,7 +42,7 @@ static double read_vgrid_value( PJ *defn, LP input, int *gridlist_count_p, PJ_GR
float *cvs;
/* do not deal with NaN coordinates */
/* cppcheck-suppress duplicateExpression */
- if( pj_is_nan(input.phi) || pj_is_nan(input.lam) )
+ if( isnan(input.phi) || isnan(input.lam) )
itable = *gridlist_count_p;
/* keep trying till we find a table that works */
diff --git a/src/pj_factors.c b/src/pj_factors.c
index e682a12d..373bd743 100644
--- a/src/pj_factors.c
+++ b/src/pj_factors.c
@@ -1,6 +1,7 @@
/* projection scale factors */
#define PJ_LIB__
#include "proj.h"
+#include "proj_math.h"
#include "projects.h"
#include <errno.h>
diff --git a/src/pj_init.c b/src/pj_init.c
index 9b06ff28..bdaf64f7 100644
--- a/src/pj_init.c
+++ b/src/pj_init.c
@@ -37,6 +37,7 @@
#include <ctype.h>
#include "proj.h"
#include "proj_internal.h"
+#include "proj_math.h"
#include "projects.h"
diff --git a/src/pj_internal.c b/src/pj_internal.c
index 891e0b9f..dc528649 100644
--- a/src/pj_internal.c
+++ b/src/pj_internal.c
@@ -438,19 +438,3 @@ void proj_log_func (PJ_CONTEXT *ctx, void *app_data, PJ_LOG_FUNCTION logf) {
if (0!=logf)
ctx->logger = logf;
}
-
-
-#if HAVE_C99_MATH
-/* proj_internal.h defines pj_is_nan as isnan */
-#else
-/*****************************************************************************/
-int pj_is_nan (double val) {
-/******************************************************************************
- Returns 0 if not a NaN and non-zero if val is a NaN.
-
- Provides an equivalent to isnan().
-******************************************************************************/
- /* cppcheck-suppress duplicateExpression */
- return val != val;
-}
-#endif
diff --git a/src/pj_math.c b/src/pj_math.c
new file mode 100644
index 00000000..751c2750
--- /dev/null
+++ b/src/pj_math.c
@@ -0,0 +1,71 @@
+/******************************************************************************
+ * Project: PROJ
+ * Purpose: Make C99 math functions available on C89 systems
+ * Author: Kristian Evers
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Kristian Evers
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *****************************************************************************/
+
+#include "proj_math.h"
+
+#if !(defined(HAVE_C99_MATH) && HAVE_C99_MATH)
+
+/* Compute hypotenuse */
+double pj_hypot(double x, double y) {
+ x = fabs(x);
+ y = fabs(y);
+ if ( x < y ) {
+ x /= y;
+ return ( y * sqrt( 1. + x * x ) );
+ } else {
+ y /= (x != 0.0 ? x : 1.0);
+ return ( x * sqrt( 1. + y * y ) );
+ }
+}
+
+/* Compute log(1+x) accurately */
+double pj_log1p(double x) {
+ volatile double
+ y = 1 + x,
+ z = y - 1;
+ /* Here's the explanation for this magic: y = 1 + z, exactly, and z
+ * approx x, thus log(y)/z (which is nearly constant near z = 0) returns
+ * a good approximation to the true log(1 + x)/x. The multiplication x *
+ * (log(y)/z) introduces little additional error. */
+ return z == 0 ? x : x * log(y) / z;
+}
+
+/* Compute asinh(x) accurately */
+double pj_asinh(double x) {
+ double y = fabs(x); /* Enforce odd parity */
+ y = log1p(y * (1 + y/(hypot(1.0, y) + 1)));
+ return x > 0 ? y : (x < 0 ? -y : x);
+}
+
+/* Returns 0 if not a NaN and non-zero if val is a NaN */
+int pj_isnan (double x) {
+ /* cppcheck-suppress duplicateExpression */
+ return x != x;
+}
+
+
+#endif /* !(defined(HAVE_C99_MATH) && HAVE_C99_MATH) */
diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c
index aed4685b..70110746 100644
--- a/src/proj_4D_api.c
+++ b/src/proj_4D_api.c
@@ -30,6 +30,7 @@
#include <errno.h>
#include "proj.h"
#include "proj_internal.h"
+#include "proj_math.h"
#include "projects.h"
#include "geodesic.h"
diff --git a/src/proj_etmerc.c b/src/proj_etmerc.c
index 99646d14..9a89e2b0 100644
--- a/src/proj_etmerc.c
+++ b/src/proj_etmerc.c
@@ -44,6 +44,7 @@
#include <errno.h>
#include "proj.h"
#include "projects.h"
+#include "proj_math.h"
struct pj_opaque {
@@ -62,32 +63,6 @@ PROJ_HEAD(utm, "Universal Transverse Mercator (UTM)")
#define PROJ_ETMERC_ORDER 6
-
-#ifdef _GNU_SOURCE
- inline
-#endif
-static double log1py(double x) { /* Compute log(1+x) accurately */
- volatile double
- y = 1 + x,
- z = y - 1;
- /* Here's the explanation for this magic: y = 1 + z, exactly, and z
- * approx x, thus log(y)/z (which is nearly constant near z = 0) returns
- * a good approximation to the true log(1 + x)/x. The multiplication x *
- * (log(y)/z) introduces little additional error. */
- return z == 0 ? x : x * log(y) / z;
-}
-
-
-#ifdef _GNU_SOURCE
- inline
-#endif
-static double asinhy(double x) { /* Compute asinh(x) accurately */
- double y = fabs(x); /* Enforce odd parity */
- y = log1py(y * (1 + y/(hypot(1.0, y) + 1)));
- return x < 0 ? -y : y;
-}
-
-
#ifdef _GNU_SOURCE
inline
#endif
@@ -182,7 +157,7 @@ static XY e_forward (LP lp, PJ *P) { /* Ellipsoidal, forward */
Ce = atan2 (sin_Ce*cos_Cn, hypot (sin_Cn, cos_Cn*cos_Ce));
/* compl. sph. N, E -> ell. norm. N, E */
- Ce = asinhy ( tan (Ce) ); /* Replaces: Ce = log(tan(FORTPI + Ce*0.5)); */
+ Ce = asinh ( tan (Ce) ); /* Replaces: Ce = log(tan(FORTPI + Ce*0.5)); */
Cn += clenS (Q->gtu, PROJ_ETMERC_ORDER, 2*Cn, 2*Ce, &dCn, &dCe);
Ce += dCe;
if (fabs (Ce) <= 2.623395162778) {
diff --git a/src/proj_math.h b/src/proj_math.h
new file mode 100644
index 00000000..0108a439
--- /dev/null
+++ b/src/proj_math.h
@@ -0,0 +1,55 @@
+/******************************************************************************
+ * Project: PROJ
+ * Purpose: Make C99 math functions available on C89 systems
+ * Author: Kristian Evers
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Kristian Evers
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *****************************************************************************/
+
+#include <math.h>
+
+#ifndef PROJ_MATH_H
+#define PROJ_MATH_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !(defined(HAVE_C99_MATH) && HAVE_C99_MATH)
+
+
+double pj_hypot(double x, double y);
+double pj_log1p(double x);
+double pj_asinh(double x);
+int pj_isnan(double x);
+
+#define hypot pj_hypot
+#define log1p pj_log1p
+#define asinh pj_asinh
+#define isnan pj_isnan
+
+
+#endif /* !(defined(HAVE_C99_MATH) && HAVE_C99_MATH) */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*PROJ_MATH_H */
diff --git a/src/projects.h b/src/projects.h
index 5c8d1301..d6d6e23e 100644
--- a/src/projects.h
+++ b/src/projects.h
@@ -92,11 +92,6 @@ typedef long pj_int32;
#define MAX_PATH_FILENAME 1024
#endif
-/* prototype hypot for systems where absent */
-#if !(defined(HAVE_C99_MATH) && HAVE_C99_MATH)
-extern double hypot(double, double);
-#endif
-
/* If we still haven't got M_PI*, we rely on our own defines.
* For example, this is necessary when compiling with gcc and
* the -ansi flag.