about summary refs log tree commit diff
path: root/sysdeps/libm-ieee754/s_exp2f.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-02-13 17:54:15 +0000
committerUlrich Drepper <drepper@redhat.com>1998-02-13 17:54:15 +0000
commitdc30f461575342ffeb6c0f2d5931493c1c3a91c0 (patch)
tree99243511beca706f0743fe2316854c5a30709f17 /sysdeps/libm-ieee754/s_exp2f.c
parente15867921d8f3b75deb0d91628cf9a323709ea9f (diff)
downloadglibc-dc30f461575342ffeb6c0f2d5931493c1c3a91c0.tar.gz
glibc-dc30f461575342ffeb6c0f2d5931493c1c3a91c0.tar.xz
glibc-dc30f461575342ffeb6c0f2d5931493c1c3a91c0.zip
Update.
1998-02-13 17:39  Ulrich Drepper  <drepper@cygnus.com>

	* elf/Makefile: Don't use --version-script parameter to link ld.so
	unconditionally.

1998-01-02 04:19  Geoff Keating  <geoffk@ozemail.com.au>

	* math/Makefile: Add t_exp.
	* math/libm-test.c: Tighten accuracy bounds for exp(), correct
	constants.
	* math/test-reduce.c: Remove temporarily, it seems to be broken.
	* sysdeps/libm-ieee754/e_exp.c: Use accurate table method.
	* sysdeps/libm-ieee754/e_expf.c: Use table & double precision for
	better accuracy.
	* sysdeps/libm-ieee754/s_exp2.c: Use better polynomial; correct
	algorithm for very large/very small arguments.
	* sysdeps/libm-ieee754/s_exp2f.c: Use slightly better polynomial;
	correct algorithm for very large/very small arguments; adjust for
	new table.
	* sysdeps/libm-ieee754/t_exp.c: New file.
	* sysdeps/libm-ieee754/t_exp2f.h: Use table with smaller deltas.

	* sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c: Put 'strange test'
	back, with comment that explains what breaks when you remove it :-(.

	* localedata/xfrm-test.c: Avoid integer overflow.

	* stdlib/strfmon.c: char is unsigned, sometimes.

	*sysdeps/powerpc
	* sysdeps/powerpc/Makefile: Remove quad float support.
	* sysdeps/powerpc/q_*.c: Remove, they will become an add-on.
	* sysdeps/powerpc/quad_float.h: Likewise.
	* sysdeps/powerpc/test-arith.c: Likewise.
	* sysdeps/powerpc/test-arithf.c: Likewise.

	* sysdeps/generic/s_exp2.c: Remove, we have this implemented now.
	* sysdeps/generic/s_exp2f.c: Likewise.

	* sysdeps/powerpc/bits/mathinline.h: Use underscores around __asm__,
	don't try anything if _SOFT_FLOAT.

1997-12-31  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* locale/C-ctype.c (_nl_C_LC_CTYPE_class32): Undo last change.
	* locale/programs/ld-ctype.c (CHAR_CLASS32_TRANS): Likewise.
	* wctype/wctype.c: Likewise.
	* wctype/wctype.h (_ISwxxx): Renamed from _ISxxx, all uses
	changed.  They are incompatible with the _ISxxx values from
	<ctype.h> on little endian machines.
	(_ISwbit) [__BYTE_ORDER == __LITTLE_ENDIAN]: Correctly transform
	bit number.  This fixes the real bug and restores the integrity of
	the ctype locale file.
	* wctype/wcfuncs.c: Change all _ISxxx to _ISwxxx.
	* wctype/wcfuncs_l.c: Likewise.
	* wctype/wcextra.c: Likewise.
	* wctype/wctype_l.c [__BYTE_ORDER == __LITTLE_ENDIAN]: Use correct
	byte swapping.

1998-02-09  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.S (errno): Put it
	into .bss segment instead of .common, so that aliases on it work.

	* sysdeps/unix/sysv/linux/i386/sysdep.S (errno): Add .type and
	.size directives, put into .bss segment instead of initializing it
	to 4.

1998-02-12 08:00  H.J. Lu  <hjl@gnu.org>

	* libc.map (gnu_get_libc_release, gnu_get_libc_version): Added.

	* version.c (__gnu_get_libc_release, __gnu_get_libc_version): New
	functions.
	Make names without __ weak aliases.
	(__libc_release, __libc_version): Make them static.

	* include/gnu/libc-version.h: New file.
	* Makefile (headers): Add gnu/libc-version.h.

1998-02-13  Ulrich Drepper  <drepper@cygnus.com>

	* stdlib/stdlib.h (struct drand48_data): Leave X to user macros
	and use x for member name.
	Reported by Daniel Lyddy <daniell@cs.berkeley.edu>.

	* stdlib/drand48.c: Change according to member name change.
	* stdlib/drand48_r.c: Likewise.
	* stdlib/lcong48_r.c: Likewise.
	* stdlib/lrand48.c: Likewise.
	* stdlib/lrand48_r.c: Likewise.
	* stdlib/mrand48.c: Likewise.
	* stdlib/mrand48_r.c: Likewise.
	* stdlib/seed48.c: Likewise.
	* stdlib/seed48_r.c: Likewise.
	* stdlib/srand48_r.c: Likewise.

1998-02-11  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

	* nss/test-netdb.c: Add some more test cases.

1998-02-13 11:39  Ulrich Drepper  <drepper@cygnus.com>

	* libio/iovsscanf.c: Undo last change modifying errno.

1998-02-12  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* stdio-common/vfscanf.c: Never try to read another character
	after EOF.  Don't decrement read_in after EOF, it wasn't
	incremented in the first place.
	(NEXT_WIDE_CHAR): Set First, not first.

1998-02-06 07:48  H.J. Lu  <hjl@gnu.org>

	* db/Makefile ($(inst_libdir)/libndbm.a,
	$(inst_libdir)/libndbm.so): New targets.
	* db2/Makefile: Likewise.

1998-02-12 08:20  H.J. Lu  <hjl@gnu.org>

	* sysdeps/gnu/errlist.awk (sys_errlist, sys_nerr): Create weak
	aliases if HAVE_ELF or PIC or DO_VERSIONING is not defined.

1998-02-12  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/generic/_G_config.h: Define _G_wchar_t, for C++
	<streambuf.h>.
	* sysdeps/unix/sysv/linux/_G_config.h: Likewise.

1998-02-11  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/make-syscalls.sh: Fix sed pattern when dealing with
	versioned symbols.

1998-02-13 08:14  H.J. Lu  <hjl@gnu.org>

	* libc.map (_dl_global_scope, _dl_lookup_symbol_skip,
	_dl_lookup_versioned_symbol, _dl_lookup_versioned_symbol_skip):
	Added for libdl.so.







	* elf/rtld.map: New file.  Needed to define the GLIBC_2.*

	* manual/socket.texi (Host Address Functions): Clarify description
	* sysdeps/unix/sysv/linux/alpha/bits/time.h (struct timeval):
Diffstat (limited to 'sysdeps/libm-ieee754/s_exp2f.c')
-rw-r--r--sysdeps/libm-ieee754/s_exp2f.c77
1 files changed, 41 insertions, 36 deletions
diff --git a/sysdeps/libm-ieee754/s_exp2f.c b/sysdeps/libm-ieee754/s_exp2f.c
index 05e79c9f5a..11c5d55e2e 100644
--- a/sysdeps/libm-ieee754/s_exp2f.c
+++ b/sysdeps/libm-ieee754/s_exp2f.c
@@ -38,20 +38,22 @@
 #include "t_exp2f.h"
 
 static const volatile float TWOM100 = 7.88860905e-31;
-static const volatile float huge = 1e+30;
+static const volatile float TWO127 = 1.7014118346e+38;
 
 float
 __ieee754_exp2f (float x)
 {
-  static const uint32_t a_inf = 0x7f800000;
+  static const uint32_t a_minf = 0xff800000;
+  static const float himark = (float) FLT_MAX_EXP;
+  static const float lomark = (float) (FLT_MIN_EXP - FLT_MANT_DIG - 1) - 1.0;
+
   /* Check for usual case.  */
-  if (isless (x, (float) FLT_MAX_EXP)
-      && isgreater (x, (float) (FLT_MIN_EXP - 1)))
+  if (isless (x, himark) && isgreater (x, lomark))
     {
-      static const float TWO16 = 65536.0;
-      int tval;
-      float rx, x22;
-      union ieee754_float ex2_u;
+      static const float TWO15 = 32768.0;
+      int tval, unsafe;
+      float rx, x22, result;
+      union ieee754_float ex2_u, scale_u;
       fenv_t oldenv;
 
       feholdexcept (&oldenv);
@@ -68,13 +70,13 @@ __ieee754_exp2f (float x)
 	 First, calculate rx = ex + t/256.  */
       if (x >= 0)
 	{
-	  rx = x + TWO16;
-	  rx -= TWO16;
+	  rx = x + TWO15;
+	  rx -= TWO15;
 	}
       else
 	{
-	  rx = x - TWO16;
-	  rx += TWO16;
+	  rx = x - TWO15;
++	  rx += TWO15;
 	}
       x -= rx;  /* Compute x=x1. */
       /* Compute tval = (ex*256 + t)+128.
@@ -92,40 +94,43 @@ __ieee754_exp2f (float x)
       /* 'tval & 255' is the same as 'tval%256' except that it's always
 	 positive.
 	 Compute x = x2.  */
-      x -= exp2_deltatable[tval & 255];
+      x -= __exp2_deltatable[tval & 255];
 
       /* 3. Compute ex2 = 2^(t/255+e+ex).  */
-      ex2_u.f = exp2_accuratetable[tval & 255];
-      ex2_u.ieee.exponent += tval >> 8;
+      ex2_u.f = __exp2f_atable[tval & 255];
+      tval >>= 8;
+      unsafe = abs(tval) >= -FLT_MIN_EXP - 1;
+      ex2_u.ieee.exponent += tval >> unsafe;
+      scale_u.f = 1.0;
+      scale_u.ieee.exponent += tval - (tval >> unsafe);
 
       /* 4. Approximate 2^x2 - 1, using a second-degree polynomial,
-	 2^x2 ~= sum(k=0..2 | (x2 * ln(2))^k / k! ) +
-	 so
-	 2^x2 - 1 ~= sum(k=1..4 | (x2 * ln(2))^k / k! )
-	 with error less than 2^(1/512+7e-4) * (x2 * ln(2))^3 / 3! < 1.2e-18.  */
+	 with maximum error in [-2^-9 - 2^-14, 2^-9 + 2^-14]
+	 less than 1.3e-10.  */
 
-      x22 = (.240226507f * x + .6931471806f) * ex2_u.f;
+      x22 = (.24022656679f * x + .69314736128f) * ex2_u.f;
 
       /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex).  */
       fesetenv (&oldenv);
 
-      /* Need to check: does this set FE_INEXACT correctly? */
-      return x22 * x + ex2_u.f;
+      result = x22 * x + ex2_u.f;
+
+      if (!unsafe)
+	return result;
+      else
+	return result * scale_u.f;
     }
-  /* 2^inf == inf, with no error.  */
-  else if (x == *(const float *)&a_inf)
+  /* Exceptional cases:  */
+  else if (isless (x, himark))
     {
-      return x;
+      if (x == *(const float *) &a_minf)
+	/* e^-inf == 0, with no error.  */
+	return 0;
+      else
+	/* Underflow */
+	return TWOM100 * TWOM100;
     }
-  /* Check for overflow.  */
-  else if (isgreaterequal (x, (float) FLT_MAX_EXP))
-    return huge * huge;
-  /* And underflow (including -inf).  */
-  else if (isless (x, (float) (FLT_MIN_EXP - FLT_MANT_DIG)))
-    return TWOM100 * TWOM100;
-  /* Maybe the result needs to be a denormalised number...  */
-  else if (!isnan (x))
-    return __ieee754_exp2f (x + 100.0) * TWOM100;
-  else /* isnan(x) */
-    return x + x;
+  else
+    /* Return x, if x is a NaN or Inf; or overflow, otherwise.  */
+    return TWO127*x;
 }