lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 5235970 5/5: Prefer C++11 to C99 transcendent


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 5235970 5/5: Prefer C++11 to C99 transcendentals
Date: Thu, 27 Apr 2017 11:54:07 -0400 (EDT)

branch: master
commit 5235970fa4c406dd99813890e3d836b7ef3de3d5
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Prefer C++11 to C99 transcendentals
    
    Removed workarounds that used, implemented, or approximately emulated
    C99 functions
      expm1l()
      log1pl()
    in favor of C++11 overloads
      std::expm1(long double)
      std::log1p(long double)
    Rooting out all such workarounds utterly was important not only as a
    general matter of hygiene, but also because numerous unit tests failed
    on x86_86-linux-gnu due to redundant prototypes. For now at least,
    the implementations in 'math_functors.hpp' actually call std::expm1l()
    and std::log1pl(), so that the long double versions of these functions
    are always used even with double arguments, to maintain equivalence to
    prior revisions. Although the C++11 standard does not explicitly mention
    these 'l'-suffixed functions, it says [26.8/4] that everything in C99
    <math.h> is included (subsequent paragraphs describe only additions),
    and [17.6.1.2/4] that they're in ns 'std'.
---
 Makefile.am              |   9 ----
 config_ming323.hpp       |   8 ----
 configure.ac             |   4 +-
 expm1.c                  | 107 -----------------------------------------------
 expm1.h                  |  34 ---------------
 interest_rates.cpp       |   4 +-
 math_functors.hpp        |  52 +++++++----------------
 math_functors_test.cpp   |  14 +++----
 mortality_rates_test.cpp |   2 +-
 objects.make             |   8 ----
 platform_dependent.hpp   |  14 +------
 11 files changed, 27 insertions(+), 229 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index c43865d..5a522f6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -308,7 +308,6 @@ liblmi_common_sources = \
     dbvalue.cpp \
     death_benefits.cpp \
     emit_ledger.cpp \
-    expm1.c \
     facets.cpp \
     fenv_guard.cpp \
     fenv_lmi.cpp \
@@ -617,7 +616,6 @@ test_commutation_functions_SOURCES = \
   $(common_test_objects) \
   commutation_functions.cpp \
   commutation_functions_test.cpp \
-  expm1.c \
   timer.cpp
 test_commutation_functions_CXXFLAGS = $(AM_CXXFLAGS)
 
@@ -706,7 +704,6 @@ test_global_settings_LDADD = \
 test_gpt_SOURCES = \
   $(common_test_objects) \
   commutation_functions.cpp \
-  expm1.c \
   gpt_commutation_functions.cpp \
   gpt_test.cpp \
   ihs_irc7702.cpp \
@@ -745,7 +742,6 @@ test_input_SOURCES = \
   dbdict.cpp \
   dbnames.cpp \
   dbvalue.cpp \
-  expm1.c \
   facets.cpp \
   global_settings.cpp \
   input.cpp \
@@ -798,7 +794,6 @@ test_istream_to_string_CXXFLAGS = $(AM_CXXFLAGS)
 
 test_loads_SOURCES = \
   $(common_test_objects) \
-  expm1.c \
   loads.cpp \
   loads_test.cpp \
   timer.cpp
@@ -816,7 +811,6 @@ test_materially_equal_CXXFLAGS = $(AM_CXXFLAGS)
 
 test_math_functors_SOURCES = \
   $(common_test_objects) \
-  expm1.c \
   math_functors_test.cpp \
   timer.cpp
 test_math_functors_CXXFLAGS = $(AM_CXXFLAGS)
@@ -846,7 +840,6 @@ test_miscellany_CXXFLAGS = $(AM_CXXFLAGS)
 
 test_mortality_rates_SOURCES = \
   $(common_test_objects) \
-  expm1.c \
   ihs_mortal.cpp \
   mortality_rates_test.cpp
 test_mortality_rates_CXXFLAGS = $(AM_CXXFLAGS)
@@ -927,7 +920,6 @@ test_product_file_SOURCES = \
   dbdict.cpp \
   dbnames.cpp \
   dbvalue.cpp \
-  expm1.c \
   facets.cpp \
   fund_data.cpp \
   global_settings.cpp \
@@ -1133,7 +1125,6 @@ noinst_HEADERS = \
     edit_mvc_docview_parameters.hpp \
     emit_ledger.hpp \
     exit_codes.hpp \
-    expm1.h \
     facets.hpp \
     fenv_guard.hpp \
     fenv_lmi.hpp \
diff --git a/config_ming323.hpp b/config_ming323.hpp
index 9284a4a..6eabd8b 100644
--- a/config_ming323.hpp
+++ b/config_ming323.hpp
@@ -41,14 +41,6 @@
 // Version numbers are in 'include/_mingw.h' here:
 //   http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/mingw/?cvsroot=src
 
-#if 308 <= LMI_MINGW_VERSION
-#   define LMI_COMPILER_PROVIDES_EXPM1L
-#endif // 308 <= LMI_MINGW_VERSION
-
-#if 202 <= LMI_MINGW_VERSION
-#   define LMI_COMPILER_PROVIDES_LOG1PL
-#endif // 202 <= LMI_MINGW_VERSION
-
 #if 200 <= LMI_MINGW_VERSION
 #   define LMI_COMPILER_PROVIDES_RINT
 #endif // 200 <= LMI_MINGW_VERSION
diff --git a/configure.ac b/configure.ac
index 445b837..7be29bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -265,8 +265,6 @@ dnl existing code already uses these macros so continue to 
use them instead of
 dnl the usual HAVE_EXPM1/HAVE_LOG1P
 AC_CHECK_FUNC(strtof, AC_DEFINE(LMI_COMPILER_PROVIDES_STRTOF, [1], [Define 
this if you have strtof() function]))
 AC_CHECK_FUNC(strtold, AC_DEFINE(LMI_COMPILER_PROVIDES_STRTOLD, [1], [Define 
this if you have strtold() function]))
-AC_CHECK_FUNC(expm1l, AC_DEFINE(LMI_COMPILER_PROVIDES_EXPM1L, [1], [Define 
this if you have expm1l() function]))
-AC_CHECK_FUNC(log1pl, AC_DEFINE(LMI_COMPILER_PROVIDES_LOG1PL, [1], [Define 
this if you have log1pl() function]))
 AC_CHECK_FUNC(rint, AC_DEFINE(LMI_COMPILER_PROVIDES_RINT, [1], [Define this if 
you have rint() function]))
 
 dnl === Library checks ===
@@ -582,7 +580,7 @@ if test "x$GXX" == "xyes"; then
     dnl about "-funit-at-a-time is required for inlining of functions that are
     dnl only called once" in debug builds
     dnl
-    dnl NB: this is needed for expm1.c so we must add it to CFLAGS too
+    dnl NB: this is needed for any '*.c' so we must add it to CFLAGS too
     if test "$CLANG" != "yes"; then
         LMI_C_CXX_ADD_IF_SUPPORTED(-fno-inline-functions-called-once)
     fi
diff --git a/expm1.c b/expm1.c
deleted file mode 100644
index 10e1f8c..0000000
--- a/expm1.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* This is public domain. It's not
- *   "Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 
2014, 2015, 2016, 2017 Gregory W. Chicares"
- * but including that quoted string satisfies lmi's style-conformity
- * tests. Eventually this will become part of MinGW and cygwin, and
- * will then be removed from the lmi repository. Find the original at:
- *
- * 
http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/mingw/mingwex/math/expm1.c?cvsroot=src
- *
- */
-
-/*
- * Written 2005 by Gregory W. Chicares <address@hidden>.
- * Adapted to double by Danny Smith <address@hidden>.
- * Public domain.
- *
- * F2XM1's input is constrained to (-1, +1), so the domain of
- * 'x * LOG2EL' is (-LOGE2L, +LOGE2L). Outside that domain,
- * delegating to exp() handles C99 7.12.6.3/2 range errors.
- *
- * Constants from moshier.net, file cephes/ldouble/constl.c,
- * are used instead of M_LN2 and M_LOG2E, which would not be
- * visible with 'gcc std=c99'.  The use of these extended precision
- * constants also allows gcc to replace them with x87 opcodes.
- */
-
-/* Begin local GWC modifications. */
-#include "expm1.h"
-/* End local GWC modifications. */
-
-#include <math.h> /* expl() */
-/* Begin local GWC modifications:
- * #include "cephes_mconf.h"
- */
-#if !defined LMI_COMPILER_PROVIDES_EXPM1L
-#   ifdef __GNUC__
-long double expm1l(long double x);
-#define LOGE2L  6.9314718055994530941723E-1L
-#define LOG2EL  1.4426950408889634073599E0L
-
-/*
- * http://savannah.nongnu.org/projects/lmi
- * email: <address@hidden>
- * snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
- *
- * End local GWC modifications. */
-
-long double expm1l(long double x) /* Local GWC modification: type changed. */
-{
-  if (fabs(x) < LOGE2L)
-    {
-      x *= LOG2EL;
-      __asm__("f2xm1" : "=t" (x) : "0" (x));
-      return x;
-    }
-  else
-    return exp(x) - 1.0;
-}
-
-double expm1(double x)
-{
-  if (fabs(x) < LOGE2L)
-    {
-      x *= LOG2EL;
-      __asm__("f2xm1" : "=t" (x) : "0" (x));
-      return x;
-    }
-  else
-    return exp(x) - 1.0;
-}
-
-#define SQRT2 1.41421356237309504880L
-
-long double log1pl(long double x)
-{
-  if (fabs(x) < 1.0 - 0.5 * SQRT2)
-    {
-      __asm__("fldln2\n\t" "fxch\n\t" "fyl2xp1" : "=t" (x) : "0" (x));
-      return x;
-    }
-  else
-    return log(1.0 + x);
-}
-
-/* COMPILER !! Apparently como compiles this file as C++ despite its '.c'
- * extension: else 'extern "C"' wouldn't be required (or permitted).
- */
-
-/* Begin local GWC modifications. */
-#   else // Not gcc.
-    // COMPILER !! This workaround loses some accuracy.
-#       ifdef __COMO__
-            extern "C"
-#       endif // __COMO__
-            double expm1(double x) {return expm1l(x);}
-#   endif // Not gcc.
-#endif // !defined LMI_COMPILER_PROVIDES_EXPM1L
-
-#if !defined LMI_COMPILER_PROVIDES_LOG1PL
-// COMPILER !! This workaround loses some accuracy.
-#       ifdef __COMO__
-            extern "C"
-#       endif // __COMO__
-            double log1p(double x) {return log1pl(x);}
-#endif // !defined LMI_COMPILER_PROVIDES_LOG1PL
-
-/* End local GWC modifications. */
-
diff --git a/expm1.h b/expm1.h
deleted file mode 100644
index dd0795b..0000000
--- a/expm1.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Provide expm1() [C99 7.12.6.3] for toolsets that lack it.
-//
-// Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 
2016, 2017 Gregory W. Chicares.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-//
-// http://savannah.nongnu.org/projects/lmi
-// email: <address@hidden>
-// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
-
-// The include guard has an 'lmi_' prefix to avoid conflict, because
-// 'expm1_h' is an obvious name that libraries might use.
-
-#ifndef lmi_expm1_h
-#define lmi_expm1_h
-
-#include "config.hpp"
-
-// This header provides no prototype for exmpm1() because that
-// should be the job of <cmath>, once C++ adopts C99 extensions.
-
-#endif // lmi_expm1_h
-
diff --git a/interest_rates.cpp b/interest_rates.cpp
index 8d245d4..fbaff0b 100644
--- a/interest_rates.cpp
+++ b/interest_rates.cpp
@@ -95,8 +95,8 @@ namespace
 // For the annual-effective method, transformation from annual to
 // daily and back again by naive methods would lose considerable
 // precision even when the spread and fee are zero, because i is
-// small relative to (1 + i). That is why expm1l() and log1pl() are
-// used instead of pow().
+// small relative to (1 + i). That is why std::expm1() and
+// std::log1p() are used instead of std::pow().
 //
 // If both spread and fee are zero, then the net rate should exactly
 // equal the gross rate. However, those two rates would differ
diff --git a/math_functors.hpp b/math_functors.hpp
index 88cc781..3c9c015 100644
--- a/math_functors.hpp
+++ b/math_functors.hpp
@@ -28,34 +28,12 @@
 #include "et_vector.hpp"
 
 #include <algorithm>                    // std::max(), std::min()
-#include <cmath>                        // C99 expm1(), log1p()
+#include <cmath>                        // std::expm1(), std::log1p()
 #include <functional>
 #include <stdexcept>
 #include <type_traits>
 #include <vector>
 
-// For Comeau, implement expm1l() and log1pl() using type double, not
-// long double, because of an apparent incompatibility in the way
-// Comeau and MinGW pass long doubles.
-
-#if !defined LMI_COMPILER_PROVIDES_EXPM1L
-#   if defined LMI_COMO_WITH_MINGW
-extern "C" double expm1(double);
-inline double expm1l(double x) {return expm1(x);}
-#   else  // !defined LMI_COMO_WITH_MINGW
-extern "C" long double expm1l(long double);
-#   endif // !defined LMI_COMO_WITH_MINGW
-#endif // !defined LMI_COMPILER_PROVIDES_EXPM1L
-
-#if !defined LMI_COMPILER_PROVIDES_LOG1PL
-#   if defined LMI_COMO_WITH_MINGW
-extern "C" double log1p(double);
-inline double log1pl(double x) {return log1p(x);}
-#   else  // !defined LMI_COMO_WITH_MINGW
-extern "C" long double log1pl(long double);
-#   endif // !defined LMI_COMO_WITH_MINGW
-#endif // !defined LMI_COMPILER_PROVIDES_LOG1PL
-
 // TODO ?? Write functors here for other refactorable uses of
 // std::pow() found throughout the program.
 
@@ -125,7 +103,7 @@ struct mean
 //
 // Implementation note: greater accuracy and speed are obtained by
 // applying the transformation
-//   (1+i)^n - 1 <-> expm1l(log1pl(i) * n)
+//   (1+i)^n - 1 <-> std::expm1(std::log1p(i) * n)
 // to naive power-based formulas.
 
 template<typename T, int n>
@@ -147,8 +125,8 @@ struct i_upper_n_over_n_from_i
 
         static long double const reciprocal_n = 1.0L / n;
         // naively:    (1+i)^(1/n) - 1
-        // substitute: (1+i)^n - 1 <-> expm1l(log1pl(i) * n)
-        long double z = expm1l(log1pl(i) * reciprocal_n);
+        // substitute: (1+i)^n - 1 <-> std::expm1(std::log1p(i) * n)
+        long double z = std::expm1l(std::log1pl(i) * reciprocal_n);
         return static_cast<T>(z);
         }
 };
@@ -173,8 +151,8 @@ struct i_from_i_upper_n_over_n
     T operator()(T const& i) const
         {
         // naively:    (1+i)^n - 1
-        // substitute: (1+i)^n - 1 <-> expm1l(log1pl(i) * n)
-        long double z = expm1l(log1pl(i) * n);
+        // substitute: (1+i)^n - 1 <-> std::expm1(std::log1p(i) * n)
+        long double z = std::expm1l(std::log1pl(i) * n);
         return static_cast<T>(z);
         }
 };
@@ -210,8 +188,8 @@ struct d_upper_n_from_i
 
         static long double const reciprocal_n = 1.0L / n;
         // naively:    n * (1 - (1+i)^(-1/n))
-        // substitute: (1+i)^n - 1 <-> expm1l(log1pl(i) * n)
-        long double z = -n * expm1l(log1pl(i) * -reciprocal_n);
+        // substitute: (1+i)^n - 1 <-> std::expm1(std::log1p(i) * n)
+        long double z = -n * std::expm1l(std::log1pl(i) * -reciprocal_n);
         return static_cast<T>(z);
         }
 };
@@ -247,12 +225,12 @@ struct net_i_from_gross
         //   -   (1+spread)^(1/n)
         //   -         fee *(1/n)
         //   )^n - 1
-        // substitute: (1+i)^n - 1 <-> expm1l(log1pl(i) * n)
-        long double z = expm1l
+        // substitute: (1+i)^n - 1 <-> std::expm1(std::log1p(i) * n)
+        long double z = std::expm1l
             (
-            n * log1pl
-                (   expm1l(reciprocal_n * log1pl(i))
-                -   expm1l(reciprocal_n * log1pl(spread))
+            n * std::log1pl
+                (   std::expm1l(reciprocal_n * std::log1pl(i))
+                -   std::expm1l(reciprocal_n * std::log1pl(spread))
                 -          reciprocal_n * fee
                 )
             );
@@ -312,8 +290,8 @@ struct coi_rate_from_q
             {
             static long double const reciprocal_12 = 1.0L / 12;
             // naively:    1 - (1-q)^(1/12)
-            // substitute: (1+i)^n - 1 <-> expm1l(log1pl(i) * n)
-            long double monthly_q = -expm1l(log1pl(-q) * reciprocal_12);
+            // substitute: (1+i)^n - 1 <-> std::expm1(std::log1p(i) * n)
+            long double monthly_q = -std::expm1l(std::log1pl(-q) * 
reciprocal_12);
             if(1.0L == monthly_q)
                 {
                 throw std::logic_error("Monthly q equals unity.");
diff --git a/math_functors_test.cpp b/math_functors_test.cpp
index 77e6ef3..0fa63f5 100644
--- a/math_functors_test.cpp
+++ b/math_functors_test.cpp
@@ -159,9 +159,9 @@ void sample_results()
     fenv_precision(fe_ldblprec);
     std::cout
         << std::setprecision(20)
-        << "    long double precision, expm1l and log1pl\n      "
+        << "    long double precision, std::expm1 and std::log1p\n      "
         << net_i_from_gross<double,365>()(0.0, 0.004, 0.0) << '\n'
-        << "    long double precision, pow\n      "
+        << "    long double precision, std::pow\n      "
         << net_i_from_gross_naive<double,365>()(0.0, 0.004, 0.0) << '\n'
         ;
 
@@ -170,9 +170,9 @@ void sample_results()
 #endif // defined LMI_X87
     std::cout
         << std::setprecision(20)
-        << "    double precision, expm1l and log1pl\n      "
+        << "    double precision, std::expm1 and std::log1p\n      "
         << net_i_from_gross<double,365>      ()(0.0, 0.004, 0.0) << '\n'
-        << "    double precision, pow\n      "
+        << "    double precision, std::pow\n      "
         << net_i_from_gross_naive<double,365>()(0.0, 0.004, 0.0) << '\n'
         ;
 
@@ -183,7 +183,7 @@ void sample_results()
 // different implementations.
 
 // This implementation naively uses std::pow(); it is both slower and
-// less inaccurate than an alternative using expm1l() and log1pl().
+// less inaccurate than an alternative using std::expm1() and std::log1p().
 void mete0()
 {
     double volatile x;
@@ -207,8 +207,8 @@ void mete1()
 
 void assay_speed()
 {
-    std::cout << "  Speed test: pow   \n    " << TimeAnAliquot(mete0) << '\n';
-    std::cout << "  Speed test: expm1l\n    " << TimeAnAliquot(mete1) << '\n';
+    std::cout << "  Speed test: std::pow  \n    " << TimeAnAliquot(mete0) << 
'\n';
+    std::cout << "  Speed test: std::expm1\n    " << TimeAnAliquot(mete1) << 
'\n';
 }
 
 int test_main(int, char*[])
diff --git a/mortality_rates_test.cpp b/mortality_rates_test.cpp
index b71b565..bf478a8 100644
--- a/mortality_rates_test.cpp
+++ b/mortality_rates_test.cpp
@@ -57,7 +57,7 @@ std::vector<double> annual_rates()
 ///   qm = 1 - (1-q)^(1/12)
 ///   qm = qm / (1-qm)
 /// diverges even in the tenth significant digit. Values given here
-/// use expm1() and log1p() for better accuracy.
+/// use std::expm1() and std::log1p() for better accuracy.
 
 std::vector<double> monthly_rates()
 {
diff --git a/objects.make b/objects.make
index 6e2105e..b3f0739 100644
--- a/objects.make
+++ b/objects.make
@@ -197,7 +197,6 @@ common_common_objects := \
   dbvalue.o \
   death_benefits.o \
   emit_ledger.o \
-  expm1.o \
   facets.o \
   fenv_guard.o \
   fenv_lmi.o \
@@ -549,7 +548,6 @@ commutation_functions_test$(EXEEXT): \
   $(common_test_objects) \
   commutation_functions.o \
   commutation_functions_test.o \
-  expm1.o \
   timer.o \
 
 configurable_settings_test$(EXEEXT): \
@@ -625,7 +623,6 @@ global_settings_test$(EXEEXT): \
 gpt_test$(EXEEXT): \
   $(common_test_objects) \
   commutation_functions.o \
-  expm1.o \
   gpt_commutation_functions.o \
   gpt_test.o \
   ihs_irc7702.o \
@@ -661,7 +658,6 @@ input_test$(EXEEXT): \
   dbdict.o \
   dbnames.o \
   dbvalue.o \
-  expm1.o \
   facets.o \
   global_settings.o \
   input.o \
@@ -709,7 +705,6 @@ istream_to_string_test$(EXEEXT): \
 
 loads_test$(EXEEXT): \
   $(common_test_objects) \
-  expm1.o \
   loads.o \
   loads_test.o \
   timer.o \
@@ -724,7 +719,6 @@ materially_equal_test$(EXEEXT): \
 
 math_functors_test$(EXEEXT): \
   $(common_test_objects) \
-  expm1.o \
   math_functors_test.o \
   timer.o \
 
@@ -750,7 +744,6 @@ miscellany_test$(EXEEXT): \
 
 mortality_rates_test$(EXEEXT): \
   $(common_test_objects) \
-  expm1.o \
   ihs_mortal.o \
   mortality_rates_test.o \
 
@@ -823,7 +816,6 @@ product_file_test$(EXEEXT): \
   dbdict.o \
   dbnames.o \
   dbvalue.o \
-  expm1.o \
   facets.o \
   fund_data.o \
   global_settings.o \
diff --git a/platform_dependent.hpp b/platform_dependent.hpp
index a2adcea..99090b0 100644
--- a/platform_dependent.hpp
+++ b/platform_dependent.hpp
@@ -46,9 +46,7 @@
 // that are useful but absent from the standard language: for example,
 // it is difficult to implement cgi-bin without putenv(). Some others:
 //   _wcsdup(), fileno(), strcasecmp(), strdup()
-// should be avoided in general, but are required by wx. Still others,
-// like expm1l(), are in C99 but not C++98; the way their prototypes
-// are provided for gcc varies by platform.
+// should be avoided in general, but are required by wx.
 
 #if defined __GNUC__ && defined __STRICT_ANSI__
 #   define LMI_GNUC_STRICT_ANSI
@@ -93,16 +91,6 @@
 // means, locally, wherever it's needed. As of 2017-04, getch() is no
 // longer used; this paragraph is kept lest it be reintroduced.
 
-// GNU/Linux (but not MinGW) requires including certain headers while
-// __STRICT_ANSI__ is not defined in order to get prototypes for
-// certain functions, for C++ with '-std=c++98':
-//   math.h:  expm1l() and log1pl()
-// Use the C instead of the C++ system header so that the present file
-// can be included in C as well as C++ translation units, which is
-// temporarily useful until 'expm1.c' can be removed.
-
-#include <math.h>
-
 // Although gcc may once have defined __STRICT_ANSI__ differently:
 //   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=3199
 // its intended value now is 1:



reply via email to

[Prev in Thread] Current Thread [Next in Thread]