@@ -796,6 +796,10 @@ erf 4.125
erf 27.0
erf -27.0
erf -0x1.fffffffffffff8p-2
+erf 0x1.c5bf94p-127
+erf 0x3.8b7fa8p-128
+erf -0x3.8b7f12369ded8p-1024
+erf 0x3.8b7f12369ded5518p-16384
erfc 0.0
erfc -0
@@ -128,7 +128,6 @@ static const double
* Coefficients for approximation to erf on [0,0.84375]
*/
efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */
- efx8 = 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
pp[] = { 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
-3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
-2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
@@ -211,7 +210,16 @@ __erf (double x)
if (ix < 0x3e300000) /* |x|<2**-28 */
{
if (ix < 0x00800000)
- return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */
+ {
+ /* Avoid spurious underflow. */
+ double ret = 0.0625 * (16.0 * x + (16.0 * efx) * x);
+ if (fabs (ret) < DBL_MIN)
+ {
+ double force_underflow = ret * ret;
+ math_force_eval (force_underflow);
+ }
+ return ret;
+ }
return x + efx * x;
}
z = x * x;
@@ -33,7 +33,6 @@ erx = 8.4506291151e-01, /* 0x3f58560b */
* Coefficients for approximation to erf on [0,0.84375]
*/
efx = 1.2837916613e-01, /* 0x3e0375d4 */
-efx8= 1.0270333290e+00, /* 0x3f8375d4 */
pp0 = 1.2837916613e-01, /* 0x3e0375d4 */
pp1 = -3.2504209876e-01, /* 0xbea66beb */
pp2 = -2.8481749818e-02, /* 0xbce9528f */
@@ -111,8 +110,16 @@ float __erff(float x)
if(ix < 0x3f580000) { /* |x|<0.84375 */
if(ix < 0x31800000) { /* |x|<2**-28 */
if (ix < 0x04000000)
- /*avoid underflow */
- return (float)0.125*((float)8.0*x+efx8*x);
+ {
+ /* Avoid spurious underflow. */
+ float ret = 0.0625f * (16.0f * x + (16.0f * efx) * x);
+ if (fabsf (ret) < FLT_MIN)
+ {
+ float force_underflow = ret * ret;
+ math_force_eval (force_underflow);
+ }
+ return ret;
+ }
return x + efx*x;
}
z = x*x;
@@ -97,6 +97,7 @@
*/
#include <errno.h>
+#include <float.h>
#include <math.h>
#include <math_private.h>
@@ -143,9 +144,7 @@ tiny = 1e-4931L,
one = 1.0L,
two = 2.0L,
/* 2/sqrt(pi) - 1 */
- efx = 1.2837916709551257389615890312154517168810E-1L,
- /* 8 * (2/sqrt(pi) - 1) */
- efx8 = 1.0270333367641005911692712249723613735048E0L;
+ efx = 1.2837916709551257389615890312154517168810E-1L;
/* erf(x) = x + x R(x^2)
@@ -782,7 +781,16 @@ __erfl (long double x)
if (ix < 0x3fc60000) /* |x|<2**-57 */
{
if (ix < 0x00080000)
- return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */
+ {
+ /* Avoid spurious underflow. */
+ long double ret = 0.0625 * (16.0 * x + (16.0 * efx) * x);
+ if (fabsl (ret) < LDBL_MIN)
+ {
+ long double force_underflow = ret * ret;
+ math_force_eval (force_underflow);
+ }
+ return ret;
+ }
return x + efx * x;
}
y = a + a * neval (z, TN1, NTN1) / deval (z, TD1, NTD1);
@@ -102,6 +102,7 @@
*/
#include <errno.h>
+#include <float.h>
#include <math.h>
#include <math_private.h>
#include <math_ldbl_opt.h>
@@ -149,9 +150,7 @@ tiny = 1e-300L,
one = 1.0L,
two = 2.0L,
/* 2/sqrt(pi) - 1 */
- efx = 1.2837916709551257389615890312154517168810E-1L,
- /* 8 * (2/sqrt(pi) - 1) */
- efx8 = 1.0270333367641005911692712249723613735048E0L;
+ efx = 1.2837916709551257389615890312154517168810E-1L;
/* erf(x) = x + x R(x^2)
@@ -801,10 +800,17 @@ __erfl (long double x)
if (ix < 0x00800000)
{
/* erf (-0) = -0. Unfortunately, for IBM extended double
- 0.125 * (8.0 * x + efx8 * x) for x = -0 evaluates to 0. */
+ 0.0625 * (16.0 * x + (16.0 * efx) * x) for x = -0
+ evaluates to 0. */
if (x == 0)
return x;
- return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */
+ long double ret = 0.0625 * (16.0 * x + (16.0 * efx) * x);
+ if (fabsl (ret) < LDBL_MIN)
+ {
+ long double force_underflow = ret * ret;
+ math_force_eval (force_underflow);
+ }
+ return ret;
}
return x + efx * x;
}
@@ -105,6 +105,7 @@
#include <errno.h>
+#include <float.h>
#include <math.h>
#include <math_private.h>
@@ -120,8 +121,6 @@ tiny = 1e-4931L,
*/
/* 2/sqrt(pi) - 1 */
efx = 1.2837916709551257389615890312154517168810E-1L,
- /* 8 * (2/sqrt(pi) - 1) */
- efx8 = 1.0270333367641005911692712249723613735048E0L,
pp[6] = {
1.122751350964552113068262337278335028553E6L,
@@ -272,7 +271,16 @@ __erfl (long double x)
if (ix < 0x3fde8000) /* |x|<2**-33 */
{
if (ix < 0x00080000)
- return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */
+ {
+ /* Avoid spurious underflow. */
+ long double ret = 0.0625 * (16.0 * x + (16.0 * efx) * x);
+ if (fabsl (ret) < LDBL_MIN)
+ {
+ long double force_underflow = ret * ret;
+ math_force_eval (force_underflow);
+ }
+ return ret;
+ }
return x + efx * x;
}
z = x * x;