1
2	  *********************************
3 	  * Announcing FDLIBM Version 5.3 *
4	  *********************************
5============================================================
6			FDLIBM
7============================================================
8	developed at Sun Microsystems, Inc. 
9
10What's new in FDLIBM 5.3?
11
12CONFIGURE
13	To build FDLIBM, edit the supplied Makefile or create
14	a local Makefile by running "sh configure" 
15	using the supplied configure script contributed by Nelson Beebe
16
17BUGS FIXED
18
19    1. e_pow.c incorrect results when 
20	x is very close to -1.0 and y is very large, e.g.
21  	pow(-1.0000000000000002e+00,4.5035996273704970e+15) = 0
22  	pow(-9.9999999999999978e-01,4.5035996273704970e+15) = 0
23	Correct results are close to -e and -1/e.
24
25    2. k_tan.c error was > 1 ulp target for FDLIBM
26	5.2: Worst error at least 1.45 ulp at
27	tan(1.7765241907548024E+269) = 1.7733884462610958E+16
28	5.3: Worst error 0.96 ulp
29
30NOT FIXED YET
31
32    3. Compiler failure on non-standard code
33	Statements like
34	            *(1+(int*)&t1) = 0;
35	are not standard C and cause some optimizing compilers (e.g. GCC)
36	to generate bad code under optimization.    These cases
37	are to be addressed in the next release.
38	
39FDLIBM (Freely Distributable LIBM) is a C math library 
40for machines that support IEEE 754 floating-point arithmetic. 
41In this release, only double precision is supported.
42
43FDLIBM is intended to provide a reasonably portable (see 
44assumptions below), reference quality (below one ulp for
45major functions like sin,cos,exp,log) math library 
46(libm.a).  For a copy of FDLIBM, please see
47	http://www.netlib.org/fdlibm/
48or
49	http://www.validlab.com/software/
50
51--------------
521. ASSUMPTIONS
53--------------
54FDLIBM (double precision version) assumes:
55 a.  IEEE 754 style (if not precise compliance) arithmetic;
56 b.  32 bit 2's complement integer arithmetic;
57 c.  Each double precision floating-point number must be in IEEE 754 
58     double format, and that each number can be retrieved as two 32-bit 
59     integers through the using of pointer bashing as in the example 
60     below:
61
62     Example: let y = 2.0
63	double fp number y: 	2.0
64	IEEE double format:	0x4000000000000000
65
66	Referencing y as two integers:
67	*(int*)&y,*(1+(int*)&y) =	{0x40000000,0x0} (on sparc)
68					{0x0,0x40000000} (on 386)
69
70	Note: Four macros are defined in fdlibm.h to handle this kind of
71	retrieving:
72
73	__HI(x)		the high part of a double x 
74			(sign,exponent,the first 21 significant bits)
75	__LO(x)		the least 32 significant bits of x
76	__HIp(x)	same as __HI except that the argument is a pointer
77			to a double
78	__LOp(x)	same as __LO except that the argument is a pointer
79			to a double
80	
81	To ensure obtaining correct ordering, one must define  __LITTLE_ENDIAN
82	during compilation for little endian machine (like 386,486). The 
83	default is big endian.
84
85	If the behavior of pointer bashing is undefined, one may hack on the 
86	macro in fdlibm.h.
87	
88  d. IEEE exceptions may trigger "signals" as is common in Unix
89     implementations. 
90
91-------------------
922. EXCEPTION CASES
93-------------------
94All exception cases in the FDLIBM functions will be mapped
95to one of the following four exceptions:
96
97   +-huge*huge, +-tiny*tiny,    +-1.0/0.0,	+-0.0/0.0
98    (overflow)	(underflow)  (divided-by-zero) 	(invalid)
99
100For example, ieee_log(0) is a singularity and is thus mapped to 
101	-1.0/0.0 = -infinity.
102That is, FDLIBM's log will compute -one/zero and return the
103computed value.  On an IEEE machine, this will trigger the 
104divided-by-zero exception and a negative infinity is returned by 
105default.
106
107Similarly, ieee_exp(-huge) will be mapped to tiny*tiny to generate
108an underflow signal. 
109
110
111--------------------------------
1123. STANDARD CONFORMANCE WRAPPER 
113--------------------------------
114The default FDLIBM functions (compiled with -D_IEEE_LIBM flag)  
115are in "IEEE spirit" (i.e., return the most reasonable result in 
116floating-point arithmetic). If one wants FDLIBM to comply with
117standards like SVID, X/OPEN, or POSIX/ANSI, then one can 
118create a multi-standard compliant FDLIBM. In this case, each
119function in FDLIBM is actually a standard compliant wrapper
120function.  
121
122File organization:
123    1. For FDLIBM's kernel (internal) function,
124		File name	Entry point
125		---------------------------
126		k_sin.c		__kernel_sin
127		k_tan.c		__kernel_tan
128		---------------------------
129    2. For functions that have no standards conflict 
130		File name	Entry point
131		---------------------------
132		s_sin.c		sin
133		s_erf.c		erf
134		---------------------------
135    3. Ieee754 core functions
136		File name	Entry point
137		---------------------------
138		e_exp.c		__ieee754_exp
139		e_sinh.c	__ieee754_sinh
140		---------------------------
141    4. Wrapper functions
142		File name	Entry point
143		---------------------------
144		w_exp.c		exp
145		w_sinh.c	sinh
146		---------------------------
147
148Wrapper functions will twist the result of the ieee754 
149function to comply to the standard specified by the value 
150of _LIB_VERSION 
151    if _LIB_VERSION = _IEEE_, return the ieee754 result;
152    if _LIB_VERSION = _SVID_, return SVID result;
153    if _LIB_VERSION = _XOPEN_, return XOPEN result;
154    if _LIB_VERSION = _POSIX_, return POSIX/ANSI result.
155(These are macros, see fdlibm.h for their definition.)
156
157
158--------------------------------
1594. HOW TO CREATE FDLIBM's libm.a
160--------------------------------
161There are two types of libm.a. One is IEEE only, and the other is
162multi-standard compliant (supports IEEE,XOPEN,POSIX/ANSI,SVID).
163
164To create the IEEE only libm.a, use 
165	    make "CFLAGS = -D_IEEE_LIBM"	 
166This will create an IEEE libm.a, which is smaller in size, and 
167somewhat faster.
168
169To create a multi-standard compliant libm, use
170    make "CFLAGS = -D_IEEE_MODE"   --- multi-standard fdlibm: default
171					 to IEEE
172    make "CFLAGS = -D_XOPEN_MODE"  --- multi-standard fdlibm: default
173					 to X/OPEN
174    make "CFLAGS = -D_POSIX_MODE"  --- multi-standard fdlibm: default
175					 to POSIX/ANSI
176    make "CFLAGS = -D_SVID3_MODE"  --- multi-standard fdlibm: default
177					 to SVID
178
179
180Here is how one makes a SVID compliant libm.
181    Make the library by
182		make "CFLAGS = -D_SVID3_MODE".
183    The libm.a of FDLIBM will be multi-standard compliant and 
184    _LIB_VERSION is initialized to the value _SVID_ . 
185
186    example1:
187    ---------
188	    main()
189	    {
190		double ieee_y0();
191		printf("y0(1e300) = %1.20e\n",y0(1e300));
192		exit(0);
193	    }
194
195    % cc example1.c libm.a
196    % a.out
197    y0: TLOSS error
198    ieee_y0(1e300) = 0.00000000000000000000e+00
199
200
201It is possible to change the default standard in multi-standard 
202fdlibm. Here is an example of how to do it:
203    example2:
204    ---------
205	#include "fdlibm.h"	/* must include FDLIBM's fdlibm.h */
206	main()
207	{
208		double ieee_y0();
209		_LIB_VERSION =  _IEEE_;
210		printf("IEEE: ieee_y0(1e300) = %1.20e\n",y0(1e300));
211		_LIB_VERSION = _XOPEN_;
212		printf("XOPEN ieee_y0(1e300) = %1.20e\n",y0(1e300));
213		_LIB_VERSION = _POSIX_;
214		printf("POSIX ieee_y0(1e300) = %1.20e\n",y0(1e300));
215		_LIB_VERSION = _SVID_;
216		printf("SVID  ieee_y0(1e300) = %1.20e\n",y0(1e300));
217		exit(0);
218	}
219
220    % cc example2.c libm.a
221    % a.out
222      IEEE: ieee_y0(1e300) = -1.36813604503424810557e-151
223      XOPEN ieee_y0(1e300) = 0.00000000000000000000e+00
224      POSIX ieee_y0(1e300) = 0.00000000000000000000e+00
225      y0: TLOSS error
226      SVID  ieee_y0(1e300) = 0.00000000000000000000e+00
227
228Note:	Here _LIB_VERSION is a global variable. If global variables 
229	are forbidden, then one should modify fdlibm.h to change
230	_LIB_VERSION to be a global constant. In this case, one
231	may not change the value of _LIB_VERSION as in example2.
232
233---------------------------
2345. NOTES ON PORTING FDLIBM
235---------------------------
236	Care must be taken when installing FDLIBM over existing
237	libm.a.
238	All co-existing function prototypes must agree, otherwise
239	users will encounter mysterious failures.
240
241	So far, the only known likely conflict is the declaration 
242	of the IEEE recommended function scalb:
243
244		double ieee_scalb(double,double)	(1)	SVID3 defined
245		double ieee_scalb(double,int)	(2)	IBM,DEC,...
246
247	FDLIBM follows Sun definition and use (1) as default. 
248	If one's existing libm.a uses (2), then one may raise
249	the flags _SCALB_INT during the compilation of FDLIBM
250	to get the correct function prototype.
251	(E.g., make "CFLAGS = -D_IEEE_LIBM -D_SCALB_INT".)
252	NOTE that if -D_SCALB_INT is raised, it won't be SVID3
253	conformant.
254
255--------------
2566. PROBLEMS ?
257--------------
258Please send comments and bug reports to the electronic mail address
259suggested by: 
260		fdlibm-comments AT sun.com
261
262