This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: PR29335 use MPFR for more math builtins


This patch hooks more builtins into MPFR, namely expm1, log, log2, log10,
log1p, cbrt, erf and erfc.

Tested on sparc-sun-solaris2.10, no regressions and the new testcase
changes pass as well.  I also ran the erf, erfc, log and log10 tests in
the transcendental accuaracy testsuite and got perfect results.  (The
suite has no tests for the other functions).

Okay for mainline?

		Thanks,
		--Kaveh


2006-10-25  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	PR middle-end/29335
	* builtins.c (fold_builtin_cbrt, fold_builtin_logarithm):
	Calculate compile-time constants using MPFR.
	(fold_builtin_1): Likewise handle BUILT_IN_ERF, BUILT_IN_ERFC,
	BUILT_IN_EXPM1 and BUILT_IN_LOG1P.

testsuite:
	* gcc.dg/torture/builtin-math-2.c (TESTIT): Use new helper macro.
	Add checks for log, log2, log10 and log1p.

	* gcc.dg/torture/builtin-math-3.c: Add checks for -0.0 everywhere
	we already test 0.0.  Add checks for expm1, log, log2, log10,
	log1p, cbrt, erf and erfc.

diff -rup orig/egcc-SVN20061024/gcc/builtins.c egcc-SVN20061024/gcc/builtins.c
--- orig/egcc-SVN20061024/gcc/builtins.c	2006-10-24 13:51:04.000000000 -0400
+++ egcc-SVN20061024/gcc/builtins.c	2006-10-24 22:03:30.505028458 -0400
@@ -7113,15 +7113,15 @@ fold_builtin_sqrt (tree arglist, tree ty
 static tree
 fold_builtin_cbrt (tree arglist, tree type)
 {
-  tree arg = TREE_VALUE (arglist);
+  tree arg = TREE_VALUE (arglist), res;
   const enum built_in_function fcode = builtin_mathfn_code (arg);

   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
     return NULL_TREE;

-  /* Optimize cbrt of constant value.  */
-  if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
-    return arg;
+  /* Calculate the result when the argument is a constant.  */
+  if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
+    return res;

   if (flag_unsafe_math_optimizations)
     {
@@ -7557,45 +7557,45 @@ real_dconstp (tree expr, const REAL_VALU
 }

 /* A subroutine of fold_builtin to fold the various logarithmic
-   functions.  EXP is the CALL_EXPR of a call to a builtin logN
-   function.  VALUE is the base of the logN function.  */
+   functions.  Return NULL_TREE if no simplification can me made.
+   FUNC is the corresponding MPFR logarithm function.  */

 static tree
 fold_builtin_logarithm (tree fndecl, tree arglist,
-			const REAL_VALUE_TYPE *value)
+			int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
 {
   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
     {
       tree type = TREE_TYPE (TREE_TYPE (fndecl));
-      tree arg = TREE_VALUE (arglist);
+      tree arg = TREE_VALUE (arglist), res;
       const enum built_in_function fcode = builtin_mathfn_code (arg);

-      /* Optimize logN(1.0) = 0.0.  */
-      if (real_onep (arg))
-	return build_real (type, dconst0);
-
-      /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
-	 exactly, then only do this if flag_unsafe_math_optimizations.  */
-      if (exact_real_truncate (TYPE_MODE (type), value)
-	  || flag_unsafe_math_optimizations)
-	{
-	  const REAL_VALUE_TYPE value_truncate =
-	    real_value_truncate (TYPE_MODE (type), *value);
-	  if (real_dconstp (arg, &value_truncate))
+      /* Optimize log(e) = 1.0.  We're never passed an exact 'e',
+	 instead we'll look for 'e' truncated to MODE.  So only do
+	 this if flag_unsafe_math_optimizations is set.  */
+      if (flag_unsafe_math_optimizations && func == mpfr_log)
+        {
+	  const REAL_VALUE_TYPE e_truncated =
+	    real_value_truncate (TYPE_MODE (type), dconste);
+	  if (real_dconstp (arg, &e_truncated))
 	    return build_real (type, dconst1);
 	}

+      /* Calculate the result when the argument is a constant.  */
+      if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
+	return res;
+
       /* Special case, optimize logN(expN(x)) = x.  */
       if (flag_unsafe_math_optimizations
-	  && ((value == &dconste
+	  && ((func == mpfr_log
 	       && (fcode == BUILT_IN_EXP
 		   || fcode == BUILT_IN_EXPF
 		   || fcode == BUILT_IN_EXPL))
-	      || (value == &dconst2
+	      || (func == mpfr_log2
 		  && (fcode == BUILT_IN_EXP2
 		      || fcode == BUILT_IN_EXP2F
 		      || fcode == BUILT_IN_EXP2L))
-	      || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
+	      || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
 	return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));

       /* Optimize logN(func()) for various exponential functions.  We
@@ -9045,6 +9045,18 @@ fold_builtin_1 (tree fndecl, tree arglis
 			     NULL, NULL, 0);
     break;

+    CASE_FLT_FN (BUILT_IN_ERF):
+      if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+	return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erf,
+			     NULL, NULL, 0);
+    break;
+
+    CASE_FLT_FN (BUILT_IN_ERFC):
+      if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+	return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erfc,
+			     NULL, NULL, 0);
+    break;
+
     CASE_FLT_FN (BUILT_IN_EXP):
       return fold_builtin_exponent (fndecl, arglist, mpfr_exp);

@@ -9055,14 +9067,26 @@ fold_builtin_1 (tree fndecl, tree arglis
     CASE_FLT_FN (BUILT_IN_POW10):
       return fold_builtin_exponent (fndecl, arglist, mpfr_exp10);

+    CASE_FLT_FN (BUILT_IN_EXPM1):
+      if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+	return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_expm1,
+			     NULL, NULL, 0);
+    break;
+
     CASE_FLT_FN (BUILT_IN_LOG):
-      return fold_builtin_logarithm (fndecl, arglist, &dconste);
+      return fold_builtin_logarithm (fndecl, arglist, mpfr_log);

     CASE_FLT_FN (BUILT_IN_LOG2):
-      return fold_builtin_logarithm (fndecl, arglist, &dconst2);
+      return fold_builtin_logarithm (fndecl, arglist, mpfr_log2);

     CASE_FLT_FN (BUILT_IN_LOG10):
-      return fold_builtin_logarithm (fndecl, arglist, &dconst10);
+      return fold_builtin_logarithm (fndecl, arglist, mpfr_log10);
+
+    CASE_FLT_FN (BUILT_IN_LOG1P):
+      if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+	return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_log1p,
+			     &dconstm1, NULL, false);
+    break;

     CASE_FLT_FN (BUILT_IN_POW):
       return fold_builtin_pow (fndecl, arglist, type);
diff -rup orig/egcc-SVN20061024/gcc/testsuite/gcc.dg/torture/builtin-math-2.c egcc-SVN20061024/gcc/testsuite/gcc.dg/torture/builtin-math-2.c
--- orig/egcc-SVN20061024/gcc/testsuite/gcc.dg/torture/builtin-math-2.c	2006-10-24 17:53:42.000000000 -0400
+++ egcc-SVN20061024/gcc/testsuite/gcc.dg/torture/builtin-math-2.c	2006-10-24 23:44:07.098083282 -0400
@@ -12,6 +12,12 @@ extern void foof (float);
 extern void foo (double);
 extern void fool (long double);

+#define TESTIT(FUNC, ARG) do { \
+  foof (__builtin_##FUNC##f (ARG##F)); \
+  foo (__builtin_##FUNC (ARG)); \
+  fool (__builtin_##FUNC##l (ARG##L)); \
+} while (0)
+
 void bar()
 {
   /* An argument of NaN is not evaluated at compile-time.  */
@@ -28,68 +34,55 @@ void bar()
   fool (__builtin_exp2l (-__builtin_infl()));

   /* Result overflows MPFR, which in version 2.2.x has 30 exponent bits.  */
-  foof (__builtin_exp2f (0x1p50F));
-  foo (__builtin_exp2 (0x1p50));
-  fool (__builtin_exp2l (0x1p50L));
+  TESTIT (exp2, 0x1p50);
   /* Result underflows MPFR, which in version 2.2.x has 30 exponent bits.  */
-  foof (__builtin_exp2f (-0x1p50F));
-  foo (__builtin_exp2 (-0x1p50));
-  fool (__builtin_exp2l (-0x1p50L));
+  TESTIT (exp2, -0x1p50);

   /* Result overflows GCC's REAL_VALUE_TYPE, which has 26 exponent bits.  */
-  foof (__builtin_exp2f (0x1p28F));
-  foo (__builtin_exp2 (0x1p28));
-  fool (__builtin_exp2l (0x1p28L));
+  TESTIT (exp2, 0x1p28);
   /* Result underflows GCC's REAL_VALUE_TYPE, which has 26 exponent bits.  */
-  foof (__builtin_exp2f (-0x1p28F));
-  foo (__builtin_exp2 (-0x1p28));
-  fool (__builtin_exp2l (-0x1p28L));
-
+  TESTIT (exp2, -0x1p28);
+
   /* Result overflows (even an extended) C double's mode.  */
-  foof (__builtin_exp2f (0x1p24F));
-  foo (__builtin_exp2 (0x1p24));
-  fool (__builtin_exp2l (0x1p24L));
+  TESTIT (exp2, 0x1p24);
   /* Result underflows (even an extended) C double's mode.  */
-  foof (__builtin_exp2f (-0x1p24F));
-  foo (__builtin_exp2 (-0x1p24));
-  fool (__builtin_exp2l (-0x1p24L));
+  TESTIT (exp2, -0x1p24);

   /* Ensure that normal arguments/results are folded.  */
-  foof (__builtin_exp2f (1.5F));
-  foo (__builtin_exp2 (1.5));
-  fool (__builtin_exp2l (1.5L));
-  foof (__builtin_exp2f (-1.5F));
-  foo (__builtin_exp2 (-1.5));
-  fool (__builtin_exp2l (-1.5L));
-
+  TESTIT (exp2, 1.5);
+  TESTIT (exp2, -1.5);
+
   /* The asin arg must be [-1 ... 1] inclusive.  */
-  foof (__builtin_asinf (-1.5F));
-  foof (__builtin_asinf (1.5F));
-  foo (__builtin_asin (-1.5));
-  foo (__builtin_asin (1.5));
-  fool (__builtin_asinl (-1.5L));
-  fool (__builtin_asinl (1.5L));
+  TESTIT (asin, -1.5);
+  TESTIT (asin, 1.5);

   /* The acos arg must be [-1 ... 1] inclusive.  */
-  foof (__builtin_acosf (-1.5F));
-  foof (__builtin_acosf (1.5F));
-  foo (__builtin_acos (-1.5));
-  foo (__builtin_acos (1.5));
-  fool (__builtin_acosl (-1.5L));
-  fool (__builtin_acosl (1.5L));
-
+  TESTIT (acos, -1.5);
+  TESTIT (acos, 1.5);
+
   /* The acosh arg must be [1 ... Inf] inclusive.  */
-  foof (__builtin_acoshf (0.5F));
-  foo (__builtin_acosh (0.5));
-  fool (__builtin_acoshl (0.5L));
-
-  /* The atanh arg must be [-1 ... 1] exclusive.  */
-  foof (__builtin_atanhf (-1.0F));
-  foof (__builtin_atanhf (1.0F));
-  foo (__builtin_atanh (-1.0));
-  foo (__builtin_atanh (1.0));
-  fool (__builtin_atanhl (-1.0L));
-  fool (__builtin_atanhl (1.0L));
+  TESTIT (acosh, 0.5);
+
+  /* The atanh arg must be [-1 ... 1] EXclusive.  */
+  TESTIT (atanh, -1.0);
+  TESTIT (atanh, 1.0);
+
+  /* The log* arg must be [0 ... Inf] EXclusive.  */
+  TESTIT (log, -1.0);
+  TESTIT (log, 0.0);
+  TESTIT (log, -0.0);
+
+  TESTIT (log2, -1.0);
+  TESTIT (log2, 0.0);
+  TESTIT (log2, -0.0);
+
+  TESTIT (log10, -1.0);
+  TESTIT (log10, 0.0);
+  TESTIT (log10, -0.0);
+
+  /* The log1p arg must be [-1 ... Inf] EXclusive.  */
+  TESTIT (log1p, -2.0);
+  TESTIT (log1p, -1.0);
 }

 /* { dg-final { scan-tree-dump-times "exp2 " 9 "original" } } */
@@ -107,4 +100,16 @@ void bar()
 /* { dg-final { scan-tree-dump-times "atanh " 2 "original" } } */
 /* { dg-final { scan-tree-dump-times "atanhf" 2 "original" } } */
 /* { dg-final { scan-tree-dump-times "atanhl" 2 "original" } } */
+/* { dg-final { scan-tree-dump-times "log " 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "logf" 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "logl" 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "log2 " 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "log2f" 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "log2l" 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "log10 " 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "log10f" 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "log10l" 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "log1p " 2 "original" } } */
+/* { dg-final { scan-tree-dump-times "log1pf" 2 "original" } } */
+/* { dg-final { scan-tree-dump-times "log1pl" 2 "original" } } */
 /* { dg-final { cleanup-tree-dump "original" } } */
diff -rup orig/egcc-SVN20061024/gcc/testsuite/gcc.dg/torture/builtin-math-3.c egcc-SVN20061024/gcc/testsuite/gcc.dg/torture/builtin-math-3.c
--- orig/egcc-SVN20061024/gcc/testsuite/gcc.dg/torture/builtin-math-3.c	2006-10-24 17:53:42.000000000 -0400
+++ egcc-SVN20061024/gcc/testsuite/gcc.dg/torture/builtin-math-3.c	2006-10-24 23:54:23.290197298 -0400
@@ -7,6 +7,9 @@

 /* { dg-do link } */

+/* Define "e" with as many bits as found in builtins.c:dconste.  */
+#define M_E  2.7182818284590452353602874713526624977572470936999595749669676277241
+
 /* All references to link_error should go away at compile-time.  */
 extern void link_error(int);

@@ -34,18 +37,22 @@ int main (void)
 {
   TESTIT2 (asin, -1.0, -3.15/2.0, -3.14/2.0); /* asin(-1) == -pi/2 */
   TESTIT (asin, 0.0, 0.0); /* asin(0) == 0 */
+  TESTIT (asin, -0.0, -0.0); /* asin(-0) == -0 */
   TESTIT2 (asin, 1.0, 3.14/2.0, 3.15/2.0); /* asin(1) == pi/2 */

   TESTIT2 (acos, -1.0, 3.14, 3.15); /* acos(-1) == pi */
   TESTIT2 (acos, 0.0, 3.14/2.0, 3.15/2.0); /* acos(0) == pi/2 */
+  TESTIT2 (acos, -0.0, 3.14/2.0, 3.15/2.0); /* acos(-0) == pi/2 */
   TESTIT (acos, 1.0, 0.0); /* acos(1) == 0 */

   TESTIT2 (atan, -1.0, -3.15/4.0, -3.14/4.0); /* atan(-1) == -pi/4 */
   TESTIT (atan, 0.0, 0.0); /* atan(0) == 0 */
+  TESTIT (atan, -0.0, -0.0); /* atan(-0) == -0 */
   TESTIT2 (atan, 1.0, 3.14/4.0, 3.15/4.0); /* atan(1) == pi/4 */

   TESTIT2 (asinh, -1.0, -0.89, -0.88); /* asinh(-1) == -0.881... */
   TESTIT (asinh, 0.0, 0.0); /* asinh(0) == 0 */
+  TESTIT (asinh, -0.0, -0.0); /* asinh(-0) == -0 */
   TESTIT2 (asinh, 1.0, 0.88, 0.89); /* asinh(1) == 0.881... */

   TESTIT (acosh, 1.0, 0.0); /* acosh(1) == 0. */
@@ -53,47 +60,97 @@ int main (void)

   TESTIT2 (atanh, -0.5, -0.55, -0.54); /* atanh(-0.5) == -0.549... */
   TESTIT (atanh, 0.0, 0.0); /* atanh(0) == 0 */
+  TESTIT (atanh, -0.0, -0.0); /* atanh(-0) == -0 */
   TESTIT2 (atanh, 0.5, 0.54, 0.55); /* atanh(0.5) == 0.549... */

   TESTIT2 (sin, -1.0, -0.85, -0.84); /* sin(-1) == -0.841... */
   TESTIT (sin, 0.0, 0.0); /* sin(0) == 0 */
+  TESTIT (sin, -0.0, -0.0); /* sin(-0) == -0 */
   TESTIT2 (sin, 1.0, 0.84, 0.85); /* sin(1) == 0.841... */

   TESTIT2 (cos, -1.0, 0.54, 0.55); /* cos(-1) == 0.5403... */
   TESTIT (cos, 0.0, 1.0); /* cos(0) == 1 */
+  TESTIT (cos, -0.0, 1.0); /* cos(-0) == 1 */
   TESTIT2 (cos, 1.0, 0.54, 0.55); /* cos(1) == 0.5403... */

   TESTIT2 (tan, -1.0, -1.56, 1.55); /* tan(-1) == -1.557... */
   TESTIT (tan, 0.0, 0.0); /* tan(0) == 0 */
+  TESTIT (tan, -0.0, -0.0); /* tan(-0) == -0 */
   TESTIT2 (tan, 1.0, 1.55, 1.56); /* tan(1) == 1.557... */

   TESTIT2 (sinh, -1.0, -1.18, -1.17); /* sinh(-1) == -1.175... */
   TESTIT (sinh, 0.0, 0.0); /* sinh(0) == 0 */
+  TESTIT (sinh, -0.0, -0.0); /* sinh(-0) == -0 */
   TESTIT2 (sinh, 1.0, 1.17, 1.18); /* sinh(1) == 1.175... */

   TESTIT2 (cosh, -1.0, 1.54, 1.55); /* cosh(-1) == 1.543... */
   TESTIT (cosh, 0.0, 1.0); /* cosh(0) == 1 */
+  TESTIT (cosh, -0.0, 1.0); /* cosh(-0) == 1 */
   TESTIT2 (cosh, 1.0, 1.54, 1.55); /* cosh(1) == 1.543... */

   TESTIT2 (tanh, -1.0, -0.77, -0.76); /* tanh(-1) == -0.761... */
+  TESTIT (tanh, -0.0, -0.0); /* tanh(-0) == -0 */
   TESTIT (tanh, 0.0, 0.0); /* tanh(0) == 0 */
   TESTIT2 (tanh, 1.0, 0.76, 0.77); /* tanh(1) == 0.761... */

   TESTIT2 (exp, -1.0, 0.36, 0.37); /* exp(-1) == 1/e */
+  TESTIT (exp, -0.0, 1.0); /* exp(-0) == 1 */
   TESTIT (exp, 0.0, 1.0); /* exp(0) == 1 */
   TESTIT2 (exp, 1.0, 2.71, 2.72); /* exp(1) == e */

   TESTIT (exp2, -1.0, 0.5); /* exp2(-1) == 1/2 */
+  TESTIT (exp2, -0.0, 1.0); /* exp2(-0) == 1 */
   TESTIT (exp2, 0.0, 1.0); /* exp2(0) == 1 */
   TESTIT (exp2, 1.0, 2.0); /* exp2(1) == 2 */

   TESTIT (exp10, -1.0, 0.1); /* exp10(-1) == 1/10 */
+  TESTIT (exp10, -0.0, 1.0); /* exp10(-0) == 1 */
   TESTIT (exp10, 0.0, 1.0); /* exp10(0) == 1 */
   TESTIT (exp10, 1.0, 10.0); /* exp10(1) == 10 */

   TESTIT (pow10, -1.0, 0.1); /* pow10(-1) == 1/10 */
+  TESTIT (pow10, -0.0, 1.0); /* pow10(-0) == 1 */
   TESTIT (pow10, 0.0, 1.0); /* pow10(0) == 1 */
   TESTIT (pow10, 1.0, 10.0); /* pow10(1) == 10 */

+  TESTIT2 (expm1, -1.0, -0.64, -0.63); /* expm1(-1) == 1/e - 1 */
+  TESTIT (expm1, -0.0, -0.0); /* expm1(-0) == 0 */
+  TESTIT (expm1, 0.0, 0.0); /* expm1(0) == 0 */
+  TESTIT2 (expm1, 1.0, 1.71, 1.72); /* expm1(1) == e - 1 */
+
+  TESTIT (log, 1.0, 0.0); /* log(1) == 0 */
+  TESTIT2 (log, M_E, 0.99, 1.01); /* log(e) == 1.000... */
+  TESTIT2 (log, M_E*M_E, 1.99, 2.01); /* log(e*e) == 2.000... */
+
+  TESTIT (log2, 1.0, 0.0); /* log2(1) == 0 */
+  TESTIT (log2, 2.0, 1.0); /* log2(2) == 1 */
+  TESTIT (log2, 4.0, 2.0); /* log2(4) == 2 */
+
+  TESTIT (log10, 1.0, 0.0); /* log10(1) == 0 */
+  TESTIT (log10, 10.0, 1.0); /* log10(10) == 1 */
+  TESTIT (log10, 100.0, 2.0); /* log10(100) == 2 */
+
+  TESTIT (log1p, 0.0, 0.0); /* log1p(0) == 0 */
+  TESTIT (log1p, -0.0, -0.0); /* log1p(-0) == -0 */
+  TESTIT2 (log1p, M_E-1, 0.99, 1.01); /* log1p(e-1) == 1.000... */
+  TESTIT2 (log1p, M_E*M_E-1, 1.99, 2.01); /* log1p(e*e-1) == 2.000... */
+
+  TESTIT (cbrt, -0.0, -0.0); /* cbrt(-0) == -0 */
+  TESTIT (cbrt, 0.0, 0.0); /* cbrt(0) == 0 */
+  TESTIT (cbrt, 1.0, 1.0); /* cbrt(1) == 1 */
+  TESTIT (cbrt, -1.0, -1.0); /* cbrt(-1) == -1 */
+  TESTIT (cbrt, 8.0, 2.0); /* cbrt(8) == 2 */
+  TESTIT (cbrt, -8.0, -2.0); /* cbrt(-8) == -2 */
+
+  TESTIT (erf, -0.0, -0.0); /* erf(-0) == -0 */
+  TESTIT (erf, 0.0, 0.0); /* erf(0) == 0 */
+  TESTIT2 (erf, 1.0, 0.84, 0.85); /* erf(1) == 0.842... */
+  TESTIT2 (erf, -1.0, -0.85, -0.84); /* erf(-1) == -0.842... */
+
+  TESTIT (erfc, -0.0, 1.0); /* erfc(-0) == 1 */
+  TESTIT (erfc, 0.0, 1.0); /* erfc(0) == 1 */
+  TESTIT2 (erfc, 1.0, 0.15, 0.16); /* erfc(1) == 0.157... */
+  TESTIT2 (erfc, -1.0, 1.84, 1.85); /* erfc(-1) == 1.842... */
+
   return 0;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]