]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix log10 (1) in round-downward mode (bug 16977).
authorJoseph Myers <joseph@codesourcery.com>
Fri, 23 May 2014 12:07:50 +0000 (12:07 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Fri, 23 May 2014 12:07:50 +0000 (12:07 +0000)
As with various other issues of this kind, bug 16977 is log10 (1)
wrongly returning -0 rather than +0 in round-downward mode because of
an implementation effectively in terms of log1p (x - 1).  This patch
fixes the issue in the same way used for log.

Tested x86_64 and x86 and ulps updated accordingly.  Also tested for
mips64 to confirm a fix was needed for ldbl-128 and to validate that
fix (also applied to ldbl-128ibm since that version of logl is
essentially the same as the ldbl-128 one).

[BZ #16977]
* sysdeps/i386/fpu/e_log10.S (__ieee754_log10): Take absolute
value when x - 1 is zero.
* sysdeps/i386/fpu/e_log10f.S (__ieee754_log10f): Likewise.
* sysdeps/i386/fpu/e_log10l.S (__ieee754_log10l): Likewise.
* sysdeps/ieee754/ldbl-128/e_log10l.c (__ieee754_log10l): Return
0.0L for an argument of 1.0L.
* sysdeps/ieee754/ldbl-128ibm/e_log10l.c (__ieee754_log10l):
Likewise.
* sysdeps/x86_64/fpu/e_log10l.S (__ieee754_log10l): Take absolute
value when x - 1 is zero.
* math/libm-test.inc (log10_test): Use ALL_RM_TEST.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.

ChangeLog
NEWS
math/libm-test.inc
sysdeps/i386/fpu/e_log10.S
sysdeps/i386/fpu/e_log10f.S
sysdeps/i386/fpu/e_log10l.S
sysdeps/i386/fpu/libm-test-ulps
sysdeps/ieee754/ldbl-128/e_log10l.c
sysdeps/ieee754/ldbl-128ibm/e_log10l.c
sysdeps/x86_64/fpu/e_log10l.S
sysdeps/x86_64/fpu/libm-test-ulps

index a7a9185e85e1419a6b0ab8eacb5620d2958496d1..c035c9f882bc0d427f36607bdcdff57e47fbf53a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2014-05-23  Joseph Myers  <joseph@codesourcery.com>
+
+       [BZ #16977]
+       * sysdeps/i386/fpu/e_log10.S (__ieee754_log10): Take absolute
+       value when x - 1 is zero.
+       * sysdeps/i386/fpu/e_log10f.S (__ieee754_log10f): Likewise.
+       * sysdeps/i386/fpu/e_log10l.S (__ieee754_log10l): Likewise.
+       * sysdeps/ieee754/ldbl-128/e_log10l.c (__ieee754_log10l): Return
+       0.0L for an argument of 1.0L.
+       * sysdeps/ieee754/ldbl-128ibm/e_log10l.c (__ieee754_log10l):
+       Likewise.
+       * sysdeps/x86_64/fpu/e_log10l.S (__ieee754_log10l): Take absolute
+       value when x - 1 is zero.
+       * math/libm-test.inc (log10_test): Use ALL_RM_TEST.
+       * sysdeps/i386/fpu/libm-test-ulps: Update.
+       * sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
+
 2014-05-23  Rasmus Villemoes  <rv@rasmusvillemoes.dk>
 
        * manual/filesys.texi (Scanning Directory Content): Fix prototype of
diff --git a/NEWS b/NEWS
index 8aaf2f4cb5b15f107b2ff284c8c78b6ce7e8ba14..1c44fd6e2d45d594bb265a76b0ae58a681847315 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -18,7 +18,7 @@ Version 2.20
   16760, 16770, 16786, 16789, 16791, 16799, 16800, 16815, 16823, 16824,
   16831, 16838, 16849, 16854, 16876, 16877, 16885, 16888, 16890, 16912,
   16915, 16916, 16917, 16922, 16927, 16928, 16932, 16943, 16958, 16966,
-  16967, 16965.
+  16967, 16965, 16977.
 
 * The minimum Linux kernel version that this version of the GNU C Library
   can be used with is 2.6.32.
index de7bc8ad9404b723fc2399d626b32a2468c63fb2..0d467a2195132ed367327f7345974d25e5e53e2a 100644 (file)
@@ -7798,9 +7798,7 @@ static const struct test_f_f_data log10_test_data[] =
 static void
 log10_test (void)
 {
-  START (log10, 0);
-  RUN_TEST_LOOP_f_f (log10, log10_test_data, );
-  END;
+  ALL_RM_TEST (log10, 0, log10_test_data, RUN_TEST_LOOP_f_f, END);
 }
 
 
index ce6a81abb6ee8cb2e570fad5ab01b6fe4d515562..17277084ca9858cd4868ca0342b6b64d078ebc02 100644 (file)
@@ -46,7 +46,13 @@ ENTRY(__ieee754_log10)
        fnstsw                  // x-1 : x : log10(2)
        andb    $0x45, %ah
        jz      2f
-       fstp    %st(1)          // x-1 : log10(2)
+       fxam
+       fnstsw
+       andb    $0x45, %ah
+       cmpb    $0x40, %ah
+       jne     5f
+       fabs                    // log10(1) is +0 in all rounding modes.
+5:     fstp    %st(1)          // x-1 : log10(2)
        fyl2xp1                 // log10(x)
        ret
 
index 8c207235551071373c8fefe08e8ed25ae45bf0f4..72a3b882518dcc48aa90d0d8f8dc92d3f90434d9 100644 (file)
@@ -47,7 +47,13 @@ ENTRY(__ieee754_log10f)
        fnstsw                  // x-1 : x : log10(2)
        andb    $0x45, %ah
        jz      2f
-       fstp    %st(1)          // x-1 : log10(2)
+       fxam
+       fnstsw
+       andb    $0x45, %ah
+       cmpb    $0x40, %ah
+       jne     5f
+       fabs                    // log10(1) is +0 in all rounding modes.
+5:     fstp    %st(1)          // x-1 : log10(2)
        fyl2xp1                 // log10(x)
        ret
 
index cde987b137ee4c807a108e9efeb0e9681eee01de..45b9c6d21d02d03728f326420225502b2ab456e2 100644 (file)
@@ -48,7 +48,13 @@ ENTRY(__ieee754_log10l)
        fnstsw                  // x-1 : x : log10(2)
        andb    $0x45, %ah
        jz      2f
-       fstp    %st(1)          // x-1 : log10(2)
+       fxam
+       fnstsw
+       andb    $0x45, %ah
+       cmpb    $0x40, %ah
+       jne     5f
+       fabs                    // log10(1) is +0 in all rounding modes.
+5:     fstp    %st(1)          // x-1 : log10(2)
        fyl2xp1                 // log10(x)
        ret
 
index 946cad489b52d5706771200e194f8100c25706e3..1e8928445509e36d4066e59b5fe23fe732443666 100644 (file)
@@ -1536,6 +1536,30 @@ Function: "log10":
 ildouble: 1
 ldouble: 1
 
+Function: "log10_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log10_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log10_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
 Function: "log1p":
 ildouble: 1
 ldouble: 1
index b403f815fbe0bb31b14b9a6481f4679b28e0025d..618255f2fa332d9264ad7c9db1e2683c1f4f58fe 100644 (file)
@@ -193,6 +193,9 @@ __ieee754_log10l (long double x)
   if (hx >= 0x7fff000000000000LL)
     return (x + x);
 
+  if (x == 1.0L)
+    return 0.0L;
+
 /* separate mantissa from exponent */
 
 /* Note, frexp is used so that denormal numbers
index 1a6a4a0fa3c70dffe2536296df63f7d8dca6a54e..7477791b77a7852ecca049798830ae9527864990 100644 (file)
@@ -195,6 +195,9 @@ __ieee754_log10l (long double x)
   if (hx >= 0x7ff0000000000000LL)
     return (x + x);
 
+  if (x == 1.0L)
+    return 0.0L;
+
 /* separate mantissa from exponent */
 
 /* Note, frexp is used so that denormal numbers
index 6c07024c19ca58f45f31d991aaf6d51ab555e67c..2607ad199b8ec49fd6b85cc2fff3422a60862900 100644 (file)
@@ -46,7 +46,13 @@ ENTRY(__ieee754_log10l)
        fnstsw                  // x-1 : x : log10(2)
        andb    $0x45, %ah
        jz      2f
-       fstp    %st(1)          // x-1 : log10(2)
+       fxam
+       fnstsw
+       andb    $0x45, %ah
+       cmpb    $0x40, %ah
+       jne     5f
+       fabs                    // log10(1) is +0 in all rounding modes.
+5:     fstp    %st(1)          // x-1 : log10(2)
        fyl2xp1                 // log10(x)
        ret
 
index d47287696c6e2bdabe4bc296d8f20500c6e13f9b..bb549d2b0d724bcabf37cc845acac23eeaf32db2 100644 (file)
@@ -1611,6 +1611,30 @@ ifloat: 2
 ildouble: 1
 ldouble: 1
 
+Function: "log10_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log10_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log10_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
 Function: "log1p":
 float: 1
 ifloat: 1