Skip to content

Commit

Permalink
Improve clog, clog10 handling of values with real or imaginary part s…
Browse files Browse the repository at this point in the history
…lightly above 1 (bug 13629).
  • Loading branch information
Joseph Myers committed Jul 31, 2012
1 parent 2bc1387 commit d0419db
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 2 deletions.
16 changes: 16 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
2012-07-31 Joseph Myers <joseph@codesourcery.com>

[BZ #13629]
* math/s_clog.c (__clog): Use __log1p if larger part has absolute
value between 1.0 and 2.0 and smaller part has absolute value less
than 1.0.
* math/s_clog10.c (__clog10): Likewise.
* math/s_clog10f.c (__clog10f): Likewise.
* math/s_clog10l.c (__clog10l): Likewise.
* math/s_clogf.c (__clogf): Likewise.
* math/s_clogl.c (__clogl): Likewise.
* math/libm-test.inc (clog_test): Add more tests.
(clog10_test): Likewise.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.

2012-07-31 Florian Weimer <fweimer@redhat.com>

* stdlib/tst-secure-getenv.c: Use printf for error reporting.
Expand Down
22 changes: 22 additions & 0 deletions math/libm-test.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2484,6 +2484,17 @@ clog_test (void)
TEST_c_c (clog, 0x1p-8192L, 1.0L, 4.202628928890116882828347271652190753248e-4933L, 1.570796326794896619231321691639751442099L, UNDERFLOW_EXCEPTION);
#endif

TEST_c_c (clog, 0x1.000566p0L, 0x1.234p-10L, 8.298731898331237038231468223024422855654e-5L, 1.110938609507128729312743251313024793990e-3L);
TEST_c_c (clog, 0x1.000566p0L, 0x1.234p-100L, 8.237022655933121125560939513260027133767e-5L, 8.974094312218060110948251664314290484113e-31L);
#ifndef TEST_FLOAT
TEST_c_c (clog, -0x1.0000000123456p0L, 0x1.2345678p-30L, 2.649094282537168795982991778475646793277e-10L, 3.141592652530155111500161671113150737892L);
TEST_c_c (clog, -0x1.0000000123456p0L, 0x1.2345678p-1000L, 2.649094276923003995420209214900915462737e-10L, 3.141592653589793238462643383279502884197L);
#endif
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
TEST_c_c (clog, 0x1.00000000000000123456789abcp0L, 0x1.23456789p-60L, 9.868649107778739757272772275265050767867e-19L, 9.868649106423871142816660980898339912137e-19L);
TEST_c_c (clog, 0x1.00000000000000123456789abcp0L, 0x1.23456789p-1000L, 9.868649107778739752403260515979017248596e-19L, 1.061846605795612822522063052130030717368e-301L);
#endif

END (clog, complex);
}

Expand Down Expand Up @@ -2633,6 +2644,17 @@ clog10_test (void)
TEST_c_c (clog10, 0x1p-8191L, 1.0L, 7.300714213215805914467117112656302312931e-4933L, 6.821881769209206737428918127156778851051e-1L, UNDERFLOW_EXCEPTION);
#endif

TEST_c_c (clog10, 0x1.000566p0L, 0x1.234p-10L, 3.604093470239754109961125085078190708674e-5L, 4.824745078422174667425851670822596859720e-4L);
TEST_c_c (clog10, 0x1.000566p0L, 0x1.234p-100L, 3.577293486783822178310971763308187385546e-5L, 3.897399639875661463735636919790792140598e-31L);
#ifndef TEST_FLOAT
TEST_c_c (clog10, -0x1.0000000123456p0L, 0x1.2345678p-30L, 1.150487028947346337782682105935961875822e-10L, 1.364376353381646356131680448946397884147L);
TEST_c_c (clog10, -0x1.0000000123456p0L, 0x1.2345678p-1000L, 1.150487026509145544402795327729455391948e-10L, 1.364376353841841347485783625431355770210L);
#endif
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
TEST_c_c (clog10, 0x1.00000000000000123456789abcp0L, 0x1.23456789p-60L, 4.285899851347756188767674032946882584784e-19L, 4.285899850759344225805480528847018395861e-19L);
TEST_c_c (clog10, 0x1.00000000000000123456789abcp0L, 0x1.23456789p-1000L, 4.285899851347756186652871946325962330640e-19L, 4.611541215247321502041995872887317363241e-302L);
#endif

END (clog10, complex);
}

Expand Down
7 changes: 7 additions & 0 deletions math/s_clog.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ __clog (__complex__ double x)
else
__real__ result = __log1p (absy2) / 2.0;
}
else if (absx > 1.0 && absx < 2.0 && absy < 1.0 && scale == 0)
{
double d2m1 = (absx - 1.0) * (absx + 1.0);
if (absy >= DBL_EPSILON)
d2m1 += absy * absy;
__real__ result = __log1p (d2m1) / 2.0;
}
else
{
double d = __ieee754_hypot (absx, absy);
Expand Down
7 changes: 7 additions & 0 deletions math/s_clog10.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ __clog10 (__complex__ double x)
else
__real__ result = __log1p (absy2) * (M_LOG10E / 2.0);
}
else if (absx > 1.0 && absx < 2.0 && absy < 1.0 && scale == 0)
{
double d2m1 = (absx - 1.0) * (absx + 1.0);
if (absy >= DBL_EPSILON)
d2m1 += absy * absy;
__real__ result = __log1p (d2m1) * (M_LOG10E / 2.0);
}
else
{
double d = __ieee754_hypot (absx, absy);
Expand Down
7 changes: 7 additions & 0 deletions math/s_clog10f.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ __clog10f (__complex__ float x)
else
__real__ result = __log1pf (absy2) * ((float) M_LOG10E / 2.0f);
}
else if (absx > 1.0f && absx < 2.0f && absy < 1.0f && scale == 0)
{
float d2m1 = (absx - 1.0f) * (absx + 1.0f);
if (absy >= FLT_EPSILON)
d2m1 += absy * absy;
__real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f);
}
else
{
float d = __ieee754_hypotf (absx, absy);
Expand Down
14 changes: 14 additions & 0 deletions math/s_clog10l.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
#include <math_private.h>
#include <float.h>

/* To avoid spurious underflows, use this definition to treat IBM long
double as approximating an IEEE-style format. */
#if LDBL_MANT_DIG == 106
# undef LDBL_EPSILON
# define LDBL_EPSILON 0x1p-106L
#endif

/* log_10 (2). */
#define M_LOG10_2l 0.3010299956639811952137388947244930267682L

Expand Down Expand Up @@ -75,6 +82,13 @@ __clog10l (__complex__ long double x)
else
__real__ result = __log1pl (absy2) * (M_LOG10El / 2.0L);
}
else if (absx > 1.0L && absx < 2.0L && absy < 1.0L && scale == 0)
{
long double d2m1 = (absx - 1.0L) * (absx + 1.0L);
if (absy >= LDBL_EPSILON)
d2m1 += absy * absy;
__real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L);
}
else
{
long double d = __ieee754_hypotl (absx, absy);
Expand Down
7 changes: 7 additions & 0 deletions math/s_clogf.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ __clogf (__complex__ float x)
else
__real__ result = __log1pf (absy2) / 2.0f;
}
else if (absx > 1.0f && absx < 2.0f && absy < 1.0f && scale == 0)
{
float d2m1 = (absx - 1.0f) * (absx + 1.0f);
if (absy >= FLT_EPSILON)
d2m1 += absy * absy;
__real__ result = __log1pf (d2m1) / 2.0f;
}
else
{
float d = __ieee754_hypotf (absx, absy);
Expand Down
14 changes: 14 additions & 0 deletions math/s_clogl.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
#include <math_private.h>
#include <float.h>

/* To avoid spurious underflows, use this definition to treat IBM long
double as approximating an IEEE-style format. */
#if LDBL_MANT_DIG == 106
# undef LDBL_EPSILON
# define LDBL_EPSILON 0x1p-106L
#endif

__complex__ long double
__clogl (__complex__ long double x)
{
Expand Down Expand Up @@ -71,6 +78,13 @@ __clogl (__complex__ long double x)
else
__real__ result = __log1pl (absy2) / 2.0L;
}
else if (absx > 1.0L && absx < 2.0L && absy < 1.0L && scale == 0)
{
long double d2m1 = (absx - 1.0L) * (absx + 1.0L);
if (absy >= LDBL_EPSILON)
d2m1 += absy * absy;
__real__ result = __log1pl (d2m1) / 2.0L;
}
else
{
long double d = __ieee754_hypotl (absx, absy);
Expand Down
Loading

0 comments on commit d0419db

Please sign in to comment.