diff --git a/.gitignore b/.gitignore index 2512c0d..dfeec89 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /geos-3.8.0.tar.bz2 /check_doxygen_errors.cmake /geos-3.8.1.tar.bz2 +/geos-3.9.0.tar.bz2 diff --git a/geos.spec b/geos.spec index fa757be..fb24251 100644 --- a/geos.spec +++ b/geos.spec @@ -1,6 +1,6 @@ Name: geos -Version: 3.8.1 -Release: 3%{?dist} +Version: 3.9.0 +Release: 1%{?dist} Summary: GEOS is a C++ port of the Java Topology Suite License: LGPLv2 @@ -11,13 +11,6 @@ Source1: http://git.osgeo.org/gitea/geos/geos/raw/tag/%{version}/doc/check # Honour libsuffix Patch1: geos_libsuffix.patch -# Install libgeos.so symlink (some packages still use the C++ API) -Patch2: geos_libgeos.patch -# remove ttmath in favour of DD -# backported from upstream: https://git.osgeo.org/gitea/geos/geos/commit/bed36f15 -# simplified to drop the rm diffs for easier rebasing -# fixes https://bugzilla.redhat.com/show_bug.cgi?id=1841335 -Patch3: geos_remove_ttmath.patch BuildRequires: cmake BuildRequires: doxygen @@ -53,16 +46,13 @@ use GEOS. %autosetup -p1 cp -a %{SOURCE1} doc/check_doxygen_errors.cmake -# Goes together with Patch3: -rm -r include/geos/algorithm/ttmath - %build %cmake \ -%ifarch armv7hl aarch64 s390x - -DDISABLE_GEOS_INLINE=ON \ +%ifarch armv7hl + -DDISABLE_GEOS_INLINE=ON \ %endif - -DBUILD_DOCUMENTATION=ON + -DBUILD_DOCUMENTATION=ON %cmake_build @@ -72,11 +62,7 @@ make docs -C %{__cmake_builddir} %check -%ifarch armv7hl aarch64 s390x ppc64le -%ctest || : -%else %ctest -%endif %ldconfig_scriptlets @@ -85,7 +71,7 @@ make docs -C %{__cmake_builddir} %files %doc AUTHORS NEWS README.md %license COPYING -%{_libdir}/libgeos.so.%{version} +%{_libdir}/libgeos.so.3.9.0 %{_libdir}/libgeos_c.so.1* %files devel @@ -96,9 +82,13 @@ make docs -C %{__cmake_builddir} %{_libdir}/libgeos_c.so %{_libdir}/libgeos.so %{_libdir}/cmake/GEOS/ +%{_libdir}/pkgconfig/%{name}.pc %changelog +* Thu Dec 10 2020 Sandro Mani - 3.9.0-1 +- Update to 3.9.0 + * Mon Jul 27 2020 Fedora Release Engineering - 3.8.1-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild diff --git a/geos_libgeos.patch b/geos_libgeos.patch deleted file mode 100644 index e85cf61..0000000 --- a/geos_libgeos.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -rupN --no-dereference geos-3.8.1/CMakeLists.txt geos-3.8.1-new/CMakeLists.txt ---- geos-3.8.1/CMakeLists.txt 2020-03-11 14:56:49.830174310 +0100 -+++ geos-3.8.1-new/CMakeLists.txt 2020-03-11 14:56:49.832174317 +0100 -@@ -281,7 +281,7 @@ configure_file(cmake/geos-config.cmake - - install(TARGETS geos geos_cxx_flags - EXPORT geos-targets -- LIBRARY DESTINATION lib${LIB_SUFFIX} NAMELINK_SKIP -+ LIBRARY DESTINATION lib${LIB_SUFFIX} - ARCHIVE DESTINATION lib${LIB_SUFFIX} - RUNTIME DESTINATION bin - INCLUDES DESTINATION include diff --git a/geos_libsuffix.patch b/geos_libsuffix.patch index b9206cc..604e5fc 100644 --- a/geos_libsuffix.patch +++ b/geos_libsuffix.patch @@ -1,13 +1,13 @@ -diff -rupN --no-dereference geos-3.8.1/CMakeLists.txt geos-3.8.1-new/CMakeLists.txt ---- geos-3.8.1/CMakeLists.txt 2020-01-05 17:44:53.000000000 +0100 -+++ geos-3.8.1-new/CMakeLists.txt 2020-03-11 14:56:49.760174088 +0100 -@@ -281,16 +281,16 @@ configure_file(cmake/geos-config.cmake +diff -rupN --no-dereference geos-3.9.0/CMakeLists.txt geos-3.9.0-new/CMakeLists.txt +--- geos-3.9.0/CMakeLists.txt 2020-12-09 01:07:19.000000000 +0100 ++++ geos-3.9.0-new/CMakeLists.txt 2020-12-10 12:23:21.466732306 +0100 +@@ -300,16 +300,16 @@ configure_file(cmake/geos-config.cmake install(TARGETS geos geos_cxx_flags EXPORT geos-targets -- LIBRARY DESTINATION lib NAMELINK_SKIP +- LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib -+ LIBRARY DESTINATION lib${LIB_SUFFIX} NAMELINK_SKIP ++ LIBRARY DESTINATION lib${LIB_SUFFIX} + ARCHIVE DESTINATION lib${LIB_SUFFIX} RUNTIME DESTINATION bin INCLUDES DESTINATION include @@ -22,7 +22,7 @@ diff -rupN --no-dereference geos-3.8.1/CMakeLists.txt geos-3.8.1-new/CMakeLists. RUNTIME DESTINATION bin INCLUDES DESTINATION include ) -@@ -298,12 +298,12 @@ install(TARGETS geos_c +@@ -317,12 +317,12 @@ install(TARGETS geos_c install(EXPORT geos-targets FILE geos-targets.cmake NAMESPACE GEOS:: @@ -37,44 +37,27 @@ diff -rupN --no-dereference geos-3.8.1/CMakeLists.txt geos-3.8.1-new/CMakeLists. install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/include/geos" "${CMAKE_CURRENT_BINARY_DIR}/include/geos" -diff -rupN --no-dereference geos-3.8.1/tools/geos-config.cmake geos-3.8.1-new/tools/geos-config.cmake ---- geos-3.8.1/tools/geos-config.cmake 2019-10-29 23:44:33.000000000 +0100 -+++ geos-3.8.1-new/tools/geos-config.cmake 2020-03-11 14:56:49.760174088 +0100 -@@ -2,7 +2,7 @@ +diff -rupN --no-dereference geos-3.9.0/tools/CMakeLists.txt geos-3.9.0-new/tools/CMakeLists.txt +--- geos-3.9.0/tools/CMakeLists.txt 2020-11-30 20:08:53.000000000 +0100 ++++ geos-3.9.0-new/tools/CMakeLists.txt 2020-12-10 12:23:21.466732306 +0100 +@@ -36,7 +36,7 @@ if(NOT MSVC) - prefix=@CMAKE_INSTALL_PREFIX@ - exec_prefix=@CMAKE_INSTALL_PREFIX@/bin --libdir=@CMAKE_INSTALL_PREFIX@/lib -+libdir=@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@@LIB_SUFFIX@ + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/geos.pc +- DESTINATION lib/pkgconfig) ++ DESTINATION lib${LIB_SUFFIX}/pkgconfig) + + endif() + +diff -rupN --no-dereference geos-3.9.0/tools/geos-config.cmake geos-3.9.0-new/tools/geos-config.cmake +--- geos-3.9.0/tools/geos-config.cmake 2020-11-30 20:08:53.000000000 +0100 ++++ geos-3.9.0-new/tools/geos-config.cmake 2020-12-10 12:23:21.466732306 +0100 +@@ -1,7 +1,7 @@ + #!/bin/sh + + prefix=@ESCAPED_INSTALL_PREFIX@ +-libdir=${prefix}/lib ++libdir=${prefix}/lib@LIB_SUFFIX usage() { -@@ -44,22 +44,22 @@ case $1 in - echo -I@CMAKE_INSTALL_PREFIX@/include - ;; - --libs) -- echo -L@CMAKE_INSTALL_PREFIX@/lib -lgeos-@GEOS_VERSION_MAJOR@ -+ echo -L@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@ -lgeos-@GEOS_VERSION_MAJOR@ - ;; - --clibs) -- echo -L@CMAKE_INSTALL_PREFIX@/lib -lgeos_c -+ echo -L@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@ -lgeos_c - ;; - --cclibs) -- echo -L@CMAKE_INSTALL_PREFIX@/lib -lgeos -+ echo -L@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@ -lgeos - ;; - --static-clibs) -- echo -L@CMAKE_INSTALL_PREFIX@/lib -lgeos_c -lgeos -lm -+ echo -L@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@ -lgeos_c -lgeos -lm - ;; - --static-cclibs) -- echo -L@CMAKE_INSTALL_PREFIX@/lib -lgeos -lm -+ echo -L@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@ -lgeos -lm - ;; - --ldflags) -- echo -L@CMAKE_INSTALL_PREFIX@/lib -+ echo -L@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@ - ;; - --includes) - echo @CMAKE_INSTALL_PREFIX@/include diff --git a/geos_remove_ttmath.patch b/geos_remove_ttmath.patch deleted file mode 100644 index d52dfbb..0000000 --- a/geos_remove_ttmath.patch +++ /dev/null @@ -1,1414 +0,0 @@ -From 1111070c0a68d0a15d1488415392658a75662be4 Mon Sep 17 00:00:00 2001 -From: Paul Ramsey -Date: Thu, 16 Apr 2020 15:31:11 -0700 -Subject: [PATCH] Squashed commit of the following: - -commit ab1b004af900354f907f9a5d31ec514c2547ada4 -Author: Paul Ramsey -Date: Thu Apr 16 14:40:23 2020 -0700 - - remove ttmath in favour of DD - -commit 472c1f9a12df1a4b9628f61c93594ee162382db4 -Merge: 8ccf3bf8 312c085b -Author: Paul Ramsey -Date: Thu Apr 16 13:24:39 2020 -0700 - - Merge branch 'master' of https://git.osgeo.org/gitea/geos/geos into master-dd - -commit 8ccf3bf874a2887b40afbaca57ee67b59b5eb40b -Author: Paul Ramsey -Date: Thu Apr 16 13:10:25 2020 -0700 - - add informational comment - -commit 8fd12e02f060f8e35d36a162d81d1ef94da1b784 -Author: Paul Ramsey -Date: Thu Apr 16 12:15:00 2020 -0700 - - add in all JTS unit tests for doubledouble calculations - -commit e24af3ba8ce7eca76840164c2edd5e066bbebe28 -Author: Paul Ramsey -Date: Wed Apr 15 13:47:56 2020 -0700 - - autotools build - -commit cb5942a13c5113ae42108e0422fed9a34a465abf -Author: Paul Ramsey -Date: Wed Apr 15 13:31:28 2020 -0700 - - fix doxygen complaint? - -commit 469037a4ca75b0f4df3638256c0fff2b61d37796 -Author: Paul Ramsey -Date: Wed Apr 15 12:47:14 2020 -0700 - - change name of ifdef guard - -commit 00559ec59b56a0ec6a0481b54f0ab597324d9439 -Author: Paul Ramsey -Date: Wed Apr 15 12:40:50 2020 -0700 - - allow DD to swap in for ttmath - -commit 75e70f7f28e751f26cc3db5b4964a86f3bae518f -Author: Paul Ramsey -Date: Wed Apr 15 11:28:15 2020 -0700 - - clean build of all DD functionality from JTS - -commit e42e9bc0ea3fd35bddc892fbe51b3de5677d8e57 -Author: Paul Ramsey -Date: Tue Apr 14 17:27:45 2020 -0700 - - DD wip ---- - .codecov.yml | 1 - - Makefile.am | 1 - - configure.ac | 3 +- - doc/Doxyfile.in | 1 - - include/geos/Makefile.am | 1 + - include/geos/algorithm/CGAlgorithmsDD.h | 16 +- - include/geos/algorithm/Makefile.am | 3 +- - include/geos/algorithm/RayCrossingCounterDD.h | 1 - - include/geos/algorithm/ttmath/COPYRIGHT | 28 - - include/geos/algorithm/ttmath/Makefile.am | 24 - - include/geos/algorithm/ttmath/README | 23 - - include/geos/algorithm/ttmath/ttmath.h | 2880 -------- - include/geos/algorithm/ttmath/ttmathbig.h | 6093 ----------------- - include/geos/algorithm/ttmath/ttmathdec.h | 419 -- - include/geos/algorithm/ttmath/ttmathint.h | 1923 ------ - include/geos/algorithm/ttmath/ttmathmisc.h | 250 - - include/geos/algorithm/ttmath/ttmathobjects.h | 812 --- - include/geos/algorithm/ttmath/ttmathparser.h | 2777 -------- - include/geos/algorithm/ttmath/ttmaththreads.h | 252 - - include/geos/algorithm/ttmath/ttmathtypes.h | 718 -- - include/geos/algorithm/ttmath/ttmathuint.h | 4189 ------------ - .../geos/algorithm/ttmath/ttmathuint_noasm.h | 1038 --- - .../geos/algorithm/ttmath/ttmathuint_x86.h | 1620 ----- - .../geos/algorithm/ttmath/ttmathuint_x86_64.h | 1177 ---- - .../ttmath/ttmathuint_x86_64_msvc.asm | 551 -- - include/geos/math/DD.h | 204 + - include/geos/math/Makefile.am | 11 + - src/Makefile.am | 2 + - src/algorithm/CGAlgorithmsDD.cpp | 7 +- - src/algorithm/InteriorPointArea.cpp | 1 - - src/geom/LineString.cpp | 2 +- - src/math/DD.cpp | 403 ++ - src/math/Makefile.am | 13 + - tests/unit/Makefile.am | 1 + - tests/unit/math/DDTest.cpp | 414 ++ - 35 files changed, 1059 insertions(+), 24800 deletions(-) - delete mode 100644 include/geos/algorithm/ttmath/COPYRIGHT - delete mode 100644 include/geos/algorithm/ttmath/Makefile.am - delete mode 100644 include/geos/algorithm/ttmath/README - delete mode 100644 include/geos/algorithm/ttmath/ttmath.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathbig.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathdec.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathint.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathmisc.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathobjects.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathparser.h - delete mode 100644 include/geos/algorithm/ttmath/ttmaththreads.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathtypes.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathuint.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathuint_noasm.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathuint_x86.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathuint_x86_64.h - delete mode 100644 include/geos/algorithm/ttmath/ttmathuint_x86_64_msvc.asm - create mode 100644 include/geos/math/DD.h - create mode 100644 include/geos/math/Makefile.am - create mode 100644 src/math/DD.cpp - create mode 100644 src/math/Makefile.am - create mode 100644 tests/unit/math/DDTest.cpp - -diff --git a/Makefile.am b/Makefile.am -index dbc74514..f064d45d 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -73,5 +73,4 @@ valgrindcheck: - check-local: - ! find $(srcdir) -name '*.cpp' -o -name '*.h' | \ - grep -v tests/xmltester/tinyxml | \ -- grep -v include/geos/algorithm/ttmath | \ - xargs grep -n '[[:space:]]$$' -diff --git a/configure.ac b/configure.ac -index 86778874..80d72e36 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -421,7 +421,6 @@ AC_OUTPUT([ - include/geos/algorithm/Makefile - include/geos/algorithm/locate/Makefile - include/geos/algorithm/distance/Makefile -- include/geos/algorithm/ttmath/Makefile - include/geos/geom/Makefile - include/geos/geom/prep/Makefile - include/geos/geom/util/Makefile -@@ -436,6 +435,7 @@ AC_OUTPUT([ - include/geos/index/sweepline/Makefile - include/geos/io/Makefile - include/geos/linearref/Makefile -+ include/geos/math/Makefile - include/geos/noding/Makefile - include/geos/noding/snapround/Makefile - include/geos/operation/Makefile -@@ -468,6 +468,7 @@ AC_OUTPUT([ - src/index/sweepline/Makefile - src/io/Makefile - src/linearref/Makefile -+ src/math/Makefile - src/noding/Makefile - src/noding/snapround/Makefile - src/operation/Makefile -diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in -index c8415081..03d9e5f7 100644 ---- a/doc/Doxyfile.in -+++ b/doc/Doxyfile.in -@@ -853,7 +853,6 @@ EXCLUDE_PATTERNS = */examples/* \ - */test/* \ - */bigtest/* \ - */io/markup/* \ -- */ttmath/* \ - config.h \ - acconfig.h \ - CoordinateList.cpp \ -diff --git a/include/geos/Makefile.am b/include/geos/Makefile.am -index cc55c4ac..04e85f8f 100644 ---- a/include/geos/Makefile.am -+++ b/include/geos/Makefile.am -@@ -8,6 +8,7 @@ SUBDIRS = \ - index \ - io \ - linearref \ -+ math \ - noding \ - operation \ - planargraph \ -diff --git a/include/geos/algorithm/CGAlgorithmsDD.h b/include/geos/algorithm/CGAlgorithmsDD.h -index f596466c..583532c1 100644 ---- a/include/geos/algorithm/CGAlgorithmsDD.h -+++ b/include/geos/algorithm/CGAlgorithmsDD.h -@@ -19,17 +19,7 @@ - #ifndef GEOS_ALGORITHM_CGALGORITHMDD_H - #define GEOS_ALGORITHM_CGALGORITHMDD_H - #include --#include -- --/// \file CGAlgorithmsDD.h -- --/// \brief Close to DoubleDouble equivalent used by JTS --/// --/// Usage: `ttmath::Big` --typedef ttmath::Big DD; --//typedef ttmath::Big DD; --//typedef ttmath::Big DD; --//typedef ttmath::Big DD; -+#include - - // Forward declarations - namespace geos { -@@ -39,6 +29,8 @@ class CoordinateSequence; - } - } - -+using namespace geos::math; -+ - namespace geos { - namespace algorithm { // geos::algorithm - -@@ -139,7 +131,7 @@ public: - * The circumcentre does not necessarily lie within the triangle. For example, - * the circumcentre of an obtuse isosceles triangle lies outside the triangle. - * -- * This method uses @ref DD extended-precision arithmetic to provide more accurate -+ * This method uses @ref geos::math::DD extended-precision arithmetic to provide more accurate - * results than [circumcentre(Coordinate, Coordinate, Coordinate)] - * (@ref geos::geom::Triangle::circumcentre(const Coordinate& p0, const Coordinate& p1, const Coordinate& p2)). - * -diff --git a/include/geos/algorithm/Makefile.am b/include/geos/algorithm/Makefile.am -index 717e63d8..dbd5a619 100644 ---- a/include/geos/algorithm/Makefile.am -+++ b/include/geos/algorithm/Makefile.am -@@ -3,8 +3,7 @@ - # - SUBDIRS = \ - locate \ -- distance \ -- ttmath -+ distance - - EXTRA_DIST = - -diff --git a/include/geos/algorithm/RayCrossingCounterDD.h b/include/geos/algorithm/RayCrossingCounterDD.h -index 2328ab3e..d7ba41e3 100644 ---- a/include/geos/algorithm/RayCrossingCounterDD.h -+++ b/include/geos/algorithm/RayCrossingCounterDD.h -@@ -22,7 +22,6 @@ - - #include - #include --#include - - #include - -diff --git a/include/geos/math/DD.h b/include/geos/math/DD.h -new file mode 100644 -index 00000000..7bcbb183 ---- /dev/null -+++ b/include/geos/math/DD.h -@@ -0,0 +1,204 @@ -+/********************************************************************** -+ * -+ * GEOS - Geometry Engine Open Source -+ * http://geos.osgeo.org -+ * -+ * Copyright (C) 2020 Crunchy Data -+ * -+ * This is free software; you can redistribute and/or modify it under -+ * the terms of the GNU Lesser General Public Licence as published -+ * by the Free Software Foundation. -+ * See the COPYING file for more information. -+ * -+ **********************************************************************/ -+ -+/** -+ * Implements extended-precision floating-point numbers -+ * which maintain 106 bits (approximately 30 decimal digits) of precision. -+ *

-+ * A DoubleDouble uses a representation containing two double-precision values. -+ * A number x is represented as a pair of doubles, x.hi and x.lo, -+ * such that the number represented by x is x.hi + x.lo, where -+ *

-+ *    |x.lo| <= 0.5*ulp(x.hi)
-+ * 
-+ * and ulp(y) means "unit in the last place of y". -+ * The basic arithmetic operations are implemented using -+ * convenient properties of IEEE-754 floating-point arithmetic. -+ *

-+ * The range of values which can be represented is the same as in IEEE-754. -+ * The precision of the representable numbers -+ * is twice as great as IEEE-754 double precision. -+ *

-+ * The correctness of the arithmetic algorithms relies on operations -+ * being performed with standard IEEE-754 double precision and rounding. -+ * This is the Java standard arithmetic model, but for performance reasons -+ * Java implementations are not -+ * constrained to using this standard by default. -+ * Some processors (notably the Intel Pentium architecture) perform -+ * floating point operations in (non-IEEE-754-standard) extended-precision. -+ * A JVM implementation may choose to use the non-standard extended-precision -+ * as its default arithmetic mode. -+ * To prevent this from happening, this code uses the -+ * Java strictfp modifier, -+ * which forces all operations to take place in the standard IEEE-754 rounding model. -+ *

-+ * The API provides both a set of value-oriented operations -+ * and a set of mutating operations. -+ * Value-oriented operations treat DoubleDouble values as -+ * immutable; operations on them return new objects carrying the result -+ * of the operation. This provides a simple and safe semantics for -+ * writing DoubleDouble expressions. However, there is a performance -+ * penalty for the object allocations required. -+ * The mutable interface updates object values in-place. -+ * It provides optimum memory performance, but requires -+ * care to ensure that aliasing errors are not created -+ * and constant values are not changed. -+ *

-+ * For example, the following code example constructs three DD instances: -+ * two to hold the input values and one to hold the result of the addition. -+ *

-+ *     DD a = new DD(2.0);
-+ *     DD b = new DD(3.0);
-+ *     DD c = a.add(b);
-+ * 
-+ * In contrast, the following approach uses only one object: -+ *
-+ *     DD a = new DD(2.0);
-+ *     a.selfAdd(3.0);
-+ * 
-+ *

-+ * This implementation uses algorithms originally designed variously by -+ * Knuth, Kahan, Dekker, and Linnainmaa. -+ * Douglas Priest developed the first C implementation of these techniques. -+ * Other more recent C++ implementation are due to Keith M. Briggs and David Bailey et al. -+ * -+ *

References

-+ *
    -+ *
  • Priest, D., Algorithms for Arbitrary Precision Floating Point Arithmetic, -+ * in P. Kornerup and D. Matula, Eds., Proc. 10th Symposium on Computer Arithmetic, -+ * IEEE Computer Society Press, Los Alamitos, Calif., 1991. -+ *
  • Yozo Hida, Xiaoye S. Li and David H. Bailey, -+ * Quad-Double Arithmetic: Algorithms, Implementation, and Application, -+ * manuscript, Oct 2000; Lawrence Berkeley National Laboratory Report BNL-46996. -+ *
  • David Bailey, High Precision Software Directory; -+ * http://crd.lbl.gov/~dhbailey/mpdist/index.html -+ *
-+ * -+ * -+ * @author Martin Davis -+ * -+ */ -+ -+#ifndef GEOS_MATH_DD_H -+#define GEOS_MATH_DD_H -+ -+#include -+ -+namespace geos { -+namespace math { // geos.math -+ -+/** -+ * \class DD -+ * -+ * \brief -+ * Wrapper for DoubleDouble higher precision mathematics -+ * operations. -+ */ -+class GEOS_DLL DD { -+ private: -+ static constexpr double SPLIT = 134217729.0; // 2^27+1, for IEEE double -+ double hi; -+ double lo; -+ -+ int magnitude(double x) const; -+ int signum() const; -+ DD rint() const; -+ -+ -+ public: -+ DD(double p_hi, double p_lo) : hi(p_hi), lo(p_lo) {}; -+ DD(double x) : hi(x), lo(0.0) {}; -+ DD(const DD &dd) : hi(dd.hi), lo(dd.lo) {}; -+ DD() : hi(0.0), lo(0.0) {}; -+ -+ bool operator==(const DD &rhs) const -+ { -+ return hi == rhs.hi && lo == rhs.lo; -+ } -+ -+ bool operator!=(const DD &rhs) const -+ { -+ return hi != rhs.hi || lo != rhs.lo; -+ } -+ -+ bool operator<(const DD &rhs) const -+ { -+ return (hi < rhs.hi) || (hi == rhs.hi && lo < rhs.lo); -+ } -+ -+ bool operator<=(const DD &rhs) const -+ { -+ return (hi < rhs.hi) || (hi == rhs.hi && lo <= rhs.lo); -+ } -+ -+ bool operator>(const DD &rhs) const -+ { -+ return (hi > rhs.hi) || (hi == rhs.hi && lo > rhs.lo); -+ } -+ -+ bool operator>=(const DD &rhs) const -+ { -+ return (hi > rhs.hi) || (hi == rhs.hi && lo >= rhs.lo); -+ } -+ -+ friend DD operator+ (const DD &lhs, const DD &rhs); -+ friend DD operator+ (const DD &lhs, double rhs); -+ friend DD operator- (const DD &lhs, const DD &rhs); -+ friend DD operator- (const DD &lhs, double rhs); -+ friend DD operator* (const DD &lhs, const DD &rhs); -+ friend DD operator* (const DD &lhs, double rhs); -+ friend DD operator/ (const DD &lhs, const DD &rhs); -+ friend DD operator/ (const DD &lhs, double rhs); -+ -+ static DD determinant(const DD &x1, const DD &y1, const DD &x2, const DD &y2); -+ static DD determinant(double x1, double y1, double x2, double y2); -+ static DD abs(const DD &d); -+ static DD pow(const DD &d, int exp); -+ static DD trunc(const DD &d); -+ -+ bool isNaN() const; -+ bool isNegative() const; -+ bool isPositive() const; -+ bool isZero() const; -+ double doubleValue() const; -+ double ToDouble() const { return doubleValue(); } -+ int intValue() const; -+ DD negate() const; -+ DD reciprocal() const; -+ DD floor() const; -+ DD ceil() const; -+ -+ void selfAdd(const DD &d); -+ void selfAdd(double p_hi, double p_lo); -+ void selfAdd(double y); -+ -+ void selfSubtract(const DD &d); -+ void selfSubtract(double p_hi, double p_lo); -+ void selfSubtract(double y); -+ -+ void selfMultiply(double p_hi, double p_lo); -+ void selfMultiply(const DD &d); -+ void selfMultiply(double y); -+ -+ void selfDivide(double p_hi, double p_lo); -+ void selfDivide(const DD &d); -+ void selfDivide(double y); -+}; -+ -+ -+} // namespace geos::math -+} // namespace geos -+ -+ -+#endif // GEOS_MATH_DD_H -diff --git a/include/geos/math/Makefile.am b/include/geos/math/Makefile.am -new file mode 100644 -index 00000000..5396b951 ---- /dev/null -+++ b/include/geos/math/Makefile.am -@@ -0,0 +1,11 @@ -+# -+# This file is part of project GEOS (http://trac.osgeo.org/geos/) -+# -+SUBDIRS = -+ -+EXTRA_DIST = -+ -+geosdir = $(includedir)/geos/math -+ -+geos_HEADERS = \ -+ DD.h -diff --git a/src/Makefile.am b/src/Makefile.am -index 1bba8e87..ea465248 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -7,6 +7,7 @@ SUBDIRS = \ - index \ - io \ - linearref \ -+ math \ - noding \ - operation \ - planargraph \ -@@ -39,6 +40,7 @@ libgeos_la_LIBADD = \ - index/libindex.la \ - io/libio.la \ - linearref/liblinearref.la \ -+ math/libmath.la \ - noding/libnoding.la \ - operation/liboperation.la \ - planargraph/libplanargraph.la \ -diff --git a/src/algorithm/CGAlgorithmsDD.cpp b/src/algorithm/CGAlgorithmsDD.cpp -index c25c1f28..c484c1f6 100644 ---- a/src/algorithm/CGAlgorithmsDD.cpp -+++ b/src/algorithm/CGAlgorithmsDD.cpp -@@ -35,7 +35,7 @@ namespace { - double constexpr DP_SAFE_EPSILON = 1e-15; - - inline int --OrientationDD(DD const& dd) -+OrientationDD(const DD &dd) - { - static DD const zero(0.0); - if(dd < zero) { -@@ -49,10 +49,7 @@ OrientationDD(DD const& dd) - return CGAlgorithmsDD::STRAIGHT; - } - --// inline std::string ToStringDD(DD const& dd) --// { --// return dd.ToString(); --// } -+ - } - - namespace geos { -diff --git a/src/algorithm/InteriorPointArea.cpp b/src/algorithm/InteriorPointArea.cpp -index 1ddddac9..61c36fd0 100644 ---- a/src/algorithm/InteriorPointArea.cpp -+++ b/src/algorithm/InteriorPointArea.cpp -@@ -200,7 +200,6 @@ private: - // edge intersects scan line, so add a crossing - double xInt = intersection(p0, p1, scanY); - crossings.push_back(xInt); -- //checkIntersectionDD(p0, p1, scanY, xInt); - } - - void findBestMidpoint(vector& crossings) -diff --git a/src/geom/LineString.cpp b/src/geom/LineString.cpp -index 65f86a0d..ac5d7fe6 100644 ---- a/src/geom/LineString.cpp -+++ b/src/geom/LineString.cpp -@@ -45,7 +45,7 @@ using namespace geos::algorithm; - namespace geos { - namespace geom { // geos::geom - --LineString::~LineString(){}; -+LineString::~LineString(){} - - /*protected*/ - LineString::LineString(const LineString& ls) -diff --git a/src/math/DD.cpp b/src/math/DD.cpp -new file mode 100644 -index 00000000..673e9217 ---- /dev/null -+++ b/src/math/DD.cpp -@@ -0,0 +1,403 @@ -+/********************************************************************** -+ * -+ * GEOS - Geometry Engine Open Source -+ * http://geos.osgeo.org -+ * -+ * Copyright (C) 2020 Crunchy Data -+ * -+ * This is free software; you can redistribute and/or modify it under -+ * the terms of the GNU Lesser General Public Licence as published -+ * by the Free Software Foundation. -+ * See the COPYING file for more information. -+ * -+ **********************************************************************/ -+ -+#include -+ -+#include -+#include -+ -+namespace geos { -+namespace math { // geos.util -+ -+ -+/* private */ -+int -+DD::magnitude(double x) const -+{ -+ double xAbs = std::fabs(x); -+ double xLog10 = std::log(xAbs) / std::log(10); -+ int xMag = (int) std::floor(xLog10); -+ /** -+ * Since log computation is inexact, there may be an off-by-one error -+ * in the computed magnitude. -+ * Following tests that magnitude is correct, and adjusts it if not -+ */ -+ double xApprox = std::pow(10, xMag); -+ if (xApprox * 10 <= xAbs) -+ xMag += 1; -+ -+ return xMag; -+} -+ -+/* public */ -+bool DD::isNaN() const -+{ -+ return std::isnan(hi); -+} -+/* public */ -+bool DD::isNegative() const -+{ -+ return hi < 0.0 || (hi == 0.0 && lo < 0.0); -+} -+/* public */ -+bool DD::isPositive() const -+{ -+ return hi > 0.0 || (hi == 0.0 && lo > 0.0); -+} -+/* public */ -+bool DD::isZero() const -+{ -+ return hi == 0.0 && lo == 0.0; -+} -+ -+/* public */ -+double DD::doubleValue() const -+{ -+ return hi + lo; -+} -+ -+/* public */ -+int DD::intValue() const -+{ -+ return (int) hi; -+} -+ -+/* public */ -+void DD::selfAdd(const DD &y) -+{ -+ return selfAdd(y.hi, y.lo); -+} -+ -+/* public */ -+void DD::selfAdd(double yhi, double ylo) -+{ -+ double H, h, T, t, S, s, e, f; -+ S = hi + yhi; -+ T = lo + ylo; -+ e = S - hi; -+ f = T - lo; -+ s = S-e; -+ t = T-f; -+ s = (yhi-e)+(hi-s); -+ t = (ylo-f)+(lo-t); -+ e = s+T; H = S+e; h = e+(S-H); e = t+h; -+ -+ double zhi = H + e; -+ double zlo = e + (H - zhi); -+ hi = zhi; -+ lo = zlo; -+ return; -+} -+ -+/* public */ -+void DD::selfAdd(double y) -+{ -+ double H, h, S, s, e, f; -+ S = hi + y; -+ e = S - hi; -+ s = S - e; -+ s = (y - e) + (hi - s); -+ f = s + lo; -+ H = S + f; -+ h = f + (S - H); -+ hi = H + h; -+ lo = h + (H - hi); -+ return; -+} -+ -+/* public */ -+DD operator+(const DD &lhs, const DD &rhs) -+{ -+ DD rv(lhs.hi, lhs.lo); -+ rv.selfAdd(rhs); -+ return rv; -+} -+ -+/* public */ -+DD operator+(const DD &lhs, double rhs) -+{ -+ DD rv(lhs.hi, lhs.lo); -+ rv.selfAdd(rhs); -+ return rv; -+} -+ -+/* public */ -+void DD::selfSubtract(const DD &d) -+{ -+ return selfAdd(-1*d.hi, -1*d.lo); -+} -+ -+/* public */ -+void DD::selfSubtract(double p_hi, double p_lo) -+{ -+ return selfAdd(-1*p_hi, -1*p_lo); -+} -+ -+/* public */ -+void DD::selfSubtract(double y) -+{ -+ return selfAdd(-1*y, 0.0); -+} -+ -+/* public */ -+DD operator-(const DD &lhs, const DD &rhs) -+{ -+ DD rv(lhs.hi, lhs.lo); -+ rv.selfSubtract(rhs); -+ return rv; -+} -+ -+/* public */ -+DD operator-(const DD &lhs, double rhs) -+{ -+ DD rv(lhs.hi, lhs.lo); -+ rv.selfSubtract(rhs); -+ return rv; -+} -+ -+/* public */ -+void DD::selfMultiply(double yhi, double ylo) -+{ -+ double hx, tx, hy, ty, C, c; -+ C = SPLIT * hi; hx = C-hi; c = SPLIT * yhi; -+ hx = C-hx; tx = hi-hx; hy = c-yhi; -+ C = hi*yhi; hy = c-hy; ty = yhi-hy; -+ c = ((((hx*hy-C)+hx*ty)+tx*hy)+tx*ty)+(hi*ylo+lo*yhi); -+ double zhi = C+c; hx = C-zhi; -+ double zlo = c+hx; -+ hi = zhi; -+ lo = zlo; -+ return; -+} -+ -+/* public */ -+void DD::selfMultiply(DD const &d) -+{ -+ return selfMultiply(d.hi, d.lo); -+} -+ -+/* public */ -+void DD::selfMultiply(double y) -+{ -+ return selfMultiply(y, 0.0); -+} -+ -+/* public */ -+DD operator*(const DD &lhs, const DD &rhs) -+{ -+ DD rv(lhs.hi, lhs.lo); -+ rv.selfMultiply(rhs); -+ return rv; -+} -+ -+/* public */ -+DD operator*(const DD &lhs, double rhs) -+{ -+ DD rv(lhs.hi, lhs.lo); -+ rv.selfMultiply(rhs); -+ return rv; -+} -+ -+ -+/* public */ -+void DD::selfDivide(double yhi, double ylo) -+{ -+ double hc, tc, hy, ty, C, c, U, u; -+ C = hi/yhi; c = SPLIT*C; hc =c-C; -+ u = SPLIT*yhi; hc = c-hc; -+ tc = C-hc; hy = u-yhi; U = C * yhi; -+ hy = u-hy; ty = yhi-hy; -+ u = (((hc*hy-U)+hc*ty)+tc*hy)+tc*ty; -+ c = ((((hi-U)-u)+lo)-C*ylo)/yhi; -+ u = C+c; -+ hi = u; -+ lo = (C-u)+c; -+ return; -+} -+ -+/* public */ -+void DD::selfDivide(const DD &d) -+{ -+ return selfDivide(d.hi, d.lo); -+} -+ -+/* public */ -+void DD::selfDivide(double y) -+{ -+ return selfDivide(y, 0.0); -+} -+ -+/* public */ -+DD operator/(const DD &lhs, const DD &rhs) -+{ -+ DD rv(lhs.hi, lhs.lo); -+ rv.selfDivide(rhs); -+ return rv; -+} -+ -+/* public */ -+DD operator/(const DD &lhs, double rhs) -+{ -+ DD rv(lhs.hi, lhs.lo); -+ rv.selfDivide(rhs); -+ return rv; -+} -+ -+/* public */ -+DD DD::negate() const -+{ -+ DD rv(hi, lo); -+ if (rv.isNaN()) -+ { -+ return rv; -+ } -+ rv.hi = -hi; -+ rv.lo = -lo; -+ return rv; -+} -+ -+/* public static */ -+DD DD::reciprocal() const -+{ -+ double hc, tc, hy, ty, C, c, U, u; -+ C = 1.0/hi; -+ c = SPLIT*C; -+ hc = c-C; -+ u = SPLIT*hi; -+ hc = c-hc; tc = C-hc; hy = u-hi; U = C*hi; hy = u-hy; ty = hi-hy; -+ u = (((hc*hy-U)+hc*ty)+tc*hy)+tc*ty; -+ c = ((((1.0-U)-u))-C*lo)/hi; -+ double zhi = C+c; -+ double zlo = (C-zhi)+c; -+ return DD(zhi, zlo); -+} -+ -+DD DD::floor() const -+{ -+ DD rv(hi, lo); -+ if (isNaN()) return rv; -+ double fhi = std::floor(hi); -+ double flo = 0.0; -+ // Hi is already integral. Floor the low word -+ if (fhi == hi) { -+ flo = std::floor(lo); -+ } -+ // do we need to renormalize here? -+ rv.hi = fhi; -+ rv.lo = flo; -+ return rv; -+} -+ -+DD DD::ceil() const -+{ -+ DD rv(hi, lo); -+ if (isNaN()) return rv; -+ double fhi = std::ceil(hi); -+ double flo = 0.0; -+ // Hi is already integral. Ceil the low word -+ if (fhi == hi) { -+ flo = std::ceil(lo); -+ // do we need to renormalize here? -+ } -+ rv.hi = fhi; -+ rv.lo = flo; -+ return rv; -+} -+ -+int DD::signum() const -+{ -+ if (hi > 0) return 1; -+ if (hi < 0) return -1; -+ if (lo > 0) return 1; -+ if (lo < 0) return -1; -+ return 0; -+} -+ -+DD DD::rint() const -+{ -+ DD rv(hi, lo); -+ if (isNaN()) return rv; -+ return (rv + 0.5).floor(); -+} -+ -+/* public static */ -+DD DD::trunc(const DD &d) -+{ -+ DD rv(d); -+ if (rv.isNaN()) return rv; -+ if (rv.isPositive()) -+ return rv.floor(); -+ return rv.ceil(); -+} -+ -+/* public static */ -+DD DD::abs(const DD &d) -+{ -+ DD rv(d); -+ if (rv.isNaN()) return rv; -+ if (rv.isNegative()) -+ return rv.negate(); -+ -+ return rv; -+} -+ -+/* public static */ -+DD DD::determinant(const DD &x1, const DD &y1, const DD &x2, const DD &y2) -+{ -+ return (x1 * y2) - (y1 * x2); -+} -+ -+/* public static */ -+DD DD::determinant(double x1, double y1, double x2, double y2) -+{ -+ return determinant(DD(x1), DD(y1), DD(x2), DD(y2) ); -+} -+ -+/** -+* Computes the value of this number raised to an integral power. -+* Follows semantics of Java Math.pow as closely as possible. -+*/ -+/* public static */ -+DD DD::pow(const DD &d, int exp) -+{ -+ if (exp == 0.0) -+ return DD(1.0); -+ -+ DD r(d); -+ DD s(1.0); -+ int n = std::abs(exp); -+ -+ if (n > 1) { -+ /* Use binary exponentiation */ -+ while (n > 0) { -+ if (n % 2 == 1) { -+ s.selfMultiply(r); -+ } -+ n /= 2; -+ if (n > 0) -+ r = r*r; -+ } -+ } else { -+ s = r; -+ } -+ -+ /* Compute the reciprocal if n is negative. */ -+ if (exp < 0) -+ return s.reciprocal(); -+ return s; -+} -+ -+ -+} -+} -diff --git a/src/math/Makefile.am b/src/math/Makefile.am -new file mode 100644 -index 00000000..c30e97ea ---- /dev/null -+++ b/src/math/Makefile.am -@@ -0,0 +1,13 @@ -+# -+# This file is part of project GEOS (http://trac.osgeo.org/geos/) -+# -+SUBDIRS = -+ -+noinst_LTLIBRARIES = libmath.la -+ -+AM_CPPFLAGS = -I$(top_srcdir)/include -+ -+libmath_la_SOURCES = \ -+ DD.cpp -+ -+libmath_la_LIBADD = -diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am -index 88c4816f..3c836fc8 100644 ---- a/tests/unit/Makefile.am -+++ b/tests/unit/Makefile.am -@@ -151,6 +151,7 @@ geos_unit_SOURCES = \ - io/WKTWriterTest.cpp \ - io/WriterTest.cpp \ - linearref/LengthIndexedLineTest.cpp \ -+ math/DDTest.cpp \ - noding/BasicSegmentStringTest.cpp \ - noding/NodedSegmentStringTest.cpp \ - noding/OrientedCoordinateArrayTest.cpp \ -diff --git a/tests/unit/math/DDTest.cpp b/tests/unit/math/DDTest.cpp -new file mode 100644 -index 00000000..00a29b8f ---- /dev/null -+++ b/tests/unit/math/DDTest.cpp -@@ -0,0 +1,414 @@ -+// -+// Test Suite for geos::util::UniqueCoordinateArrayFilter class. -+ -+// geos -+ -+#include -+#include -+ -+// tut -+#include -+#include -+ -+// std -+#include -+#include -+ -+using namespace geos::math; -+ -+namespace tut { -+// -+// Test Group -+// -+ -+// Common data used in test cases. -+struct test_dd_data { -+ -+ double eps; -+ DD pi; -+ DD e; -+ -+ -+ void ensure_dd_equals(const char *str, const DD &d1, const DD &d2, double tolerance) -+ { -+ DD delta = DD::abs(d1 - d2); -+ double diff = delta.doubleValue(); -+ ensure(str, diff <= tolerance); -+ } -+ -+ void checkTrunc(const DD &x, const DD &expected) -+ { -+ DD trunc = DD::trunc(x); -+ ensure("checkTrunc", trunc == expected); -+ } -+ -+ void checkDeterminant(double x1, double y1, double x2, double y2, double expected, double errBound) -+ { -+ DD det = DD::determinant(x1, y1, x2, y2); -+ //ensure_equals("1", Angle::angle(Coordinate(10, 0)), 0.0, TOL); -+ ensure_dd_equals("checkDeterminant", det, DD(expected), errBound); -+ } -+ -+ void checkDeterminantDD(double x1, double y1, double x2, double y2, double expected, double errBound) -+ { -+ DD det = DD::determinant(DD(x1), DD(y1), DD(x2), DD(y2)); -+ ensure_dd_equals("checkDeterminantDD", det, DD(expected), errBound); -+ } -+ -+ void checkAddMult2(const DD &dd) -+ { -+ DD sum = dd + dd; -+ DD prod = dd * DD(2.0); -+ ensure_dd_equals("checkAddMult2", sum, prod, 0.0); -+ } -+ -+ void checkMultiplyDivide(const DD &a, const DD &b, double errBound) -+ { -+ DD a2 = (a * b) / b; -+ ensure_dd_equals("checkMultiplyDivide", a, a2, errBound); -+ } -+ -+ void checkDivideMultiply(const DD &a, const DD &b, double errBound) -+ { -+ DD a2 = (a / b) * b; -+ ensure_dd_equals("checkDivideMultiply", a, a2, errBound); -+ } -+ -+ /** -+ * Computes (a+b)^2 in two different ways and compares the result. -+ * For correct results, a and b should be integers. -+ */ -+ void checkBinomialSquare(double a, double b) -+ { -+ // binomial square -+ DD add(a); -+ DD bdd(b); -+ DD aPlusb = add + bdd; -+ DD abSq = aPlusb * aPlusb; -+ -+ // expansion -+ DD a2dd = add * add; -+ DD b2dd = bdd * bdd; -+ DD ab = add * bdd; -+ DD sum = b2dd + ab + ab; -+ DD diff = abSq - a2dd; -+ DD delta = diff - sum; -+ -+ ensure("isSame", diff == sum); -+ ensure("isDeltaZero", delta.isZero()); -+ } -+ -+ void checkBinomial2(double a, double b) -+ { -+ // binomial product -+ DD add(a); -+ DD bdd(b); -+ DD aPlusb = add + bdd; -+ DD aSubb = add - bdd; -+ DD abProd = aPlusb * aSubb; -+ -+ // expansion -+ DD a2dd = add * add; -+ DD b2dd = bdd * bdd; -+ -+ // this should equal b^2 -+ DD diff = (abProd - a2dd).negate(); -+ DD delta = diff - b2dd; -+ -+ ensure("isSame", diff == b2dd); -+ ensure("isDeltaZero", delta.isZero()); -+ } -+ -+ void checkReciprocal(double x, double errBound) -+ { -+ DD xdd(x); -+ DD rr = xdd.reciprocal().reciprocal(); -+ double err = (xdd - rr).doubleValue(); -+ ensure("checkReciprocal", err <= errBound); -+ } -+ -+ DD slowPow(const DD &x, int exp) -+ { -+ if (exp == 0) -+ return DD(1.0); -+ -+ int n = std::abs(exp); -+ // MD - could use binary exponentiation for better precision & speed -+ DD pow(x); -+ for (int i = 1; i < n; i++) { -+ pow = pow * x; -+ } -+ if (exp < 0) { -+ return pow.reciprocal(); -+ } -+ return pow; -+ } -+ -+ void checkPow(double x, int exp, double errBound) -+ { -+ DD xdd(x); -+ DD pow = DD::pow(xdd, exp); -+ DD pow2 = slowPow(xdd, exp); -+ double err = (pow - pow2).doubleValue(); -+ ensure("checkPow", err <= errBound); -+ } -+ -+ -+ DD arctan(DD x) -+ { -+ DD t = x; -+ DD t2 = t*t; -+ DD at(0.0); -+ DD two(2.0); -+ int k = 0; -+ DD d(1.0); -+ int sign = 1; -+ while (t.doubleValue() > eps) { -+ k++; -+ if (sign < 0) -+ at = at - (t / d); -+ else -+ at = at + (t / d); -+ -+ d = d + two; -+ t = t * t2; -+ sign = -sign; -+ } -+ return at; -+ } -+ -+ /** -+ * Uses Taylor series to compute e -+ * -+ * e = 1 + 1 + 1/2! + 1/3! + 1/4! + ... -+ */ -+ DD computeEByTaylorSeries() -+ { -+ DD s(2.0); -+ DD t(1.0); -+ double n = 1.0; -+ int i = 0; -+ while(t.doubleValue() > eps) -+ { -+ i++; -+ n += 1.0; -+ t = t / DD(n); -+ s = s + t; -+ } -+ return s; -+ } -+ -+ /** -+ * Uses Machin's arctangent formula to compute Pi: -+ * -+ * Pi / 4 = 4 arctan(1/5) - arctan(1/239) -+ */ -+ -+ DD computePiByMachin() -+ { -+ DD t1 = DD(1.0) / DD(5.0); -+ DD t2 = DD(1.0) / DD(239.0); -+ DD pi4 = (DD(4.0) * arctan(t1)) - arctan(t2); -+ DD pi = DD(4.0) * pi4; -+ return pi; -+ } -+ -+ test_dd_data(): -+ eps(1.23259516440783e-32), /* = 2^-106 */ -+ pi(DD(3.141592653589793116e+00, 1.224646799147353207e-16)), -+ e(DD(2.718281828459045091e+00, 1.445646891729250158e-16)) -+ {} -+ -+}; -+ -+typedef test_group group; -+typedef group::object object; -+ -+group test_dd_group("geos::math::DD"); -+ -+// -+// Test Cases -+// -+ -+// Test PI calculation -+template<> -+template<> -+void object::test<1> -+() -+{ -+ DD testPi = computePiByMachin(); -+ double err = std::abs((testPi - pi).doubleValue()); -+ // std::cout << "Difference from PI = " << err << std::endl; -+ ensure("Test PI calculation", err < 8*eps); -+} -+ -+// Test E calculation -+template<> -+template<> -+void object::test<2> -+() -+{ -+ DD testE = computeEByTaylorSeries(); -+ double err = std::abs((testE - e).doubleValue()); -+ // std::cout << "Difference from E = " << err << std::endl; -+ ensure("Test E calculation", err < eps); -+} -+ -+ -+// Test NaN -+template<> -+template<> -+void object::test<3> -+() -+{ -+ DD nan = DD(1.0) / DD(0.0); -+ ensure("isNan", nan.isNaN()); -+ ensure("isNan", (DD(1.0) * nan).isNaN()); -+} -+ -+// testAddMult2 -+template<> -+template<> -+void object::test<4> -+() -+{ -+ checkAddMult2(DD(3.0)); -+ checkAddMult2(DD(pi)); -+} -+ -+ -+// testMultiplyDivide -+template<> -+template<> -+void object::test<5> -+() -+{ -+ checkMultiplyDivide(DD(pi), DD(e), 1e-30); -+ checkMultiplyDivide(DD(DD(2.0)*pi), DD(e), 1e-30); -+ checkMultiplyDivide(DD(DD(0.5)*pi), DD(e), 1e-30); -+ checkMultiplyDivide(DD(39.4), DD(10), 1e-30); -+} -+ -+ -+// testDivideMultiply -+template<> -+template<> -+void object::test<6> -+() -+{ -+ checkDivideMultiply(DD(pi), DD(e), 1e-30); -+ checkDivideMultiply(DD(39.4), DD(10), 1e-30); -+} -+ -+ -+// testTrunc -+template<> -+template<> -+void object::test<7> -+() -+{ -+ checkTrunc(DD(1e16) - DD(1), DD(1e16) - DD(1)); -+ // the appropriate error bound is determined empirically -+ checkTrunc(DD(pi), DD(3)); -+ checkTrunc(DD(999.999), DD(999)); -+ -+ checkTrunc(DD(e).negate(), DD(-2)); -+ checkTrunc(DD(-999.999), DD(-999)); -+} -+ -+// testPow -+template<> -+template<> -+void object::test<8> -+() -+{ -+ checkPow(0, 3, 16 * eps); -+ checkPow(0, 3, 16 * eps); -+ checkPow(14, 3, 16 * eps); -+ checkPow(3, -5, 16 * eps); -+ checkPow(-3, 5, 16 * eps); -+ checkPow(-3, -5, 16 * eps); -+ checkPow(0.12345, -5, 1e5 * eps); -+} -+ -+ -+// testReciprocal -+template<> -+template<> -+void object::test<9> -+() -+{ -+ checkReciprocal(3.0, 0); -+ checkReciprocal(99.0, 1e-29); -+ checkReciprocal(999.0, 0); -+ checkReciprocal(314159269.0, 0); -+} -+ -+// testDeterminant -+template<> -+template<> -+void object::test<10> -+() -+{ -+ checkDeterminant(3, 8, 4, 6, -14, 0); -+ checkDeterminantDD(3, 8, 4, 6, -14, 0); -+} -+ -+// testDeterminantRobust -+template<> -+template<> -+void object::test<11> -+() -+{ -+ checkDeterminant(1.0e9, 1.0e9 - 1, 1.0e9 - 1, 1.0e9 - 2, -1, 0); -+ checkDeterminantDD(1.0e9, 1.0e9 - 1, 1.0e9 - 1, 1.0e9 - 2, -1, 0); -+} -+ -+ -+// testBinom -+template<> -+template<> -+void object::test<12> -+() -+{ -+ checkBinomialSquare(100.0, 1.0); -+ checkBinomialSquare(1000.0, 1.0); -+ checkBinomialSquare(10000.0, 1.0); -+ checkBinomialSquare(100000.0, 1.0); -+ checkBinomialSquare(1000000.0, 1.0); -+ checkBinomialSquare(1e8, 1.0); -+ checkBinomialSquare(1e10, 1.0); -+ checkBinomialSquare(1e14, 1.0); -+ // Following call will fail, because it requires 32 digits of precision -+ // checkBinomialSquare(1e16, 1.0); -+ -+ checkBinomialSquare(1e14, 291.0); -+ checkBinomialSquare(5e14, 291.0); -+ checkBinomialSquare(5e14, 345291.0); -+} -+ -+// testBinom2 -+template<> -+template<> -+void object::test<13> -+() -+{ -+ checkBinomial2(100.0, 1.0); -+ checkBinomial2(1000.0, 1.0); -+ checkBinomial2(10000.0, 1.0); -+ checkBinomial2(100000.0, 1.0); -+ checkBinomial2(1000000.0, 1.0); -+ checkBinomial2(1e8, 1.0); -+ checkBinomial2(1e10, 1.0); -+ checkBinomial2(1e14, 1.0); -+ -+ checkBinomial2(1e14, 291.0); -+ -+ checkBinomial2(5e14, 291.0); -+ checkBinomial2(5e14, 345291.0); -+} -+ -+ -+ -+} // namespace tut -+ --- -2.26.2 - diff --git a/sources b/sources index 7840291..d3b4939 100644 --- a/sources +++ b/sources @@ -1,2 +1 @@ -SHA512 (check_doxygen_errors.cmake) = 4764415b279cd7583f8ec2e0150ab2e87f12f7b9c6249ee03bf3a368c12f698c586a6b116ae892395b7d46d620f96d2a1ac6aa16ce4bbf4dc2cdedca9f12e07f -SHA512 (geos-3.8.1.tar.bz2) = 1d8d8b3ece70eb388ea128f4135c7455899f01828223b23890ad3a2401e27104efce03987676794273a9b9d4907c0add2be381ff14b8420aaa9a858cc5941056 +SHA512 (geos-3.9.0.tar.bz2) = 518be112b2e05063d97c09d0e568b784e6c65b0a7be1368cefbd481b3f4ac2d8fc89611e6e205a95f4d1740ab4f47b3929fb4c801bcf9a9e9b6ae86a54e62933