### fdlibm-5.1 README file

    	  ********************************
     	  * Announcing FDLIBM Version 5  *
    	  ********************************
    ============================================================
    			FDLIBM
    ============================================================
      (developed at SunPro, a Sun Microsystems, Inc. business.)
    		Version 5.1, 93/09/24

    FDLIBM (Freely Distributable LIBM) is a C math library
    for machines that support IEEE 754 floating-point arithmetic.
    In this release, only double precision is supported.

    FDLIBM is intended to provide a reasonably portable (see
    assumptions below), reference quality (below one ulp for
    major functions like sin,cos,exp,log) math library
    (libm.a).  For a copy of FDLIBM, please send
    e-mail to
    		fdlibm-comments@sunpro.eng.sun.com

    --------------
    1. ASSUMPTIONS
    --------------
    FDLIBM (double precision version) assumes:
     a.  IEEE 754 style (if not precise compliance) arithmetic;
     b.  32 bit 2's complement integer arithmetic;
     c.  Each double precision floating-point number must be in IEEE 754
         double format, and that each number can be retrieved as two 32-bit
         integers;

         Example: let y = 2.0
    	double fp number y: 	2.0
    	IEEE double format:	0x4000000000000000

    	Referencing y as two integers:
    	*(int*)&y,*(1+(int*)&y) =	{0x40000000,0x0} (on sparc)
    					{0x0,0x40000000} (on 386)

    	Note: FDLIBM will detect, at run time, the correct ordering of
    	      the high and low part of a floating-point number.

      d. IEEE exceptions may trigger "signals" as is common in Unix
         implementations.

    -------------------
    2. EXCEPTION CASES
    -------------------
    All exception cases in the FDLIBM functions will be mapped
    to one of the following four exceptions:

       +-huge*huge, +-tiny*tiny,    +-1.0/0.0,	+-0.0/0.0
        (overflow)	(underflow)  (divided-by-zero) 	(invalid)

    For example, log(0) is a singularity and is thus mapped to
    	-1.0/0.0 = -infinity.
    That is, FDLIBM's log will compute -one/zero and return the
    computed value.  On an IEEE machine, this will trigger the
    divided-by-zero exception and a negative infinity is returned by
    default.

    Similarly, exp(-huge) will be mapped to tiny*tiny to generate
    an underflow signal.

    --------------------------------
    3. STANDARD CONFORMANCE WRAPPER
    --------------------------------
    The default FDLIBM functions (compiled with -D_IEEE_LIBM flag)
    are in "IEEE spirit" (i.e., return the most reasonable result in
    floating-point arithmetic). If one wants FDLIBM to comply with
    standards like SVID, X/OPEN, or POSIX/ANSI, then one can
    create a multi-standard compliant FDLIBM. In this case, each
    function in FDLIBM is actually a standard compliant wrapper
    function.

    File organization:
        1. For FDLIBM's kernel (internal) function,
    		File name	Entry point
    		---------------------------
    		k_sin.c		__kernel_sin
    		k_tan.c		__kernel_tan
    		---------------------------
        2. For functions that have no standards conflict
    		File name	Entry point
    		---------------------------
    		s_sin.c		sin
    		s_erf.c		erf
    		---------------------------
        3. Ieee754 core functions
    		File name	Entry point
    		---------------------------
    		e_exp.c		__ieee754_exp
    		e_sinh.c	__ieee754_sinh
    		---------------------------
        4. Wrapper functions
    		File name	Entry point
    		---------------------------
    		w_exp.c		exp
    		w_sinh.c	sinh
    		---------------------------

    Wrapper functions will twist the result of the ieee754
    function to comply to the standard specified by the value
    of _LIB_VERSION
        if _LIB_VERSION = _IEEE_, return the ieee754 result;
        if _LIB_VERSION = _SVID_, return SVID result;
        if _LIB_VERSION = _XOPEN_, return XOPEN result;
        if _LIB_VERSION = _POSIX_, return POSIX/ANSI result.
    (These are macros, see fdlibm.h for their definition.)

    --------------------------------
    4. HOW TO CREATE FDLIBM's libm.a
    --------------------------------
    There are two types of libm.a. One is IEEE only, and the other is
    multi-standard compliant (supports IEEE,XOPEN,POSIX/ANSI,SVID).

    To create the IEEE only libm.a, use
    	    make "CFLAGS = -D_IEEE_LIBM"
    This will create an IEEE libm.a, which is smaller in size, and
    somewhat faster.

    To create a multi-standard compliant libm, use
        make "CFLAGS = -D_IEEE_MODE"   --- multi-standard fdlibm: default
    					 to IEEE
        make "CFLAGS = -D_XOPEN_MODE"  --- multi-standard fdlibm: default
    					 to X/OPEN
        make "CFLAGS = -D_POSIX_MODE"  --- multi-standard fdlibm: default
    					 to POSIX/ANSI
        make "CFLAGS = -D_SVID3_MODE"  --- multi-standard fdlibm: default
    					 to SVID

    Here is how one makes a SVID compliant libm.
        Make the library by
    		make "CFLAGS = -D_SVID3_MODE".
        The libm.a of FDLIBM will be multi-standard compliant and
        _LIB_VERSION is initialized to the value _SVID_ .

        example1:
        ---------
    	    main()
    	    {
    		double y0();
    		printf("y0(1e300) = %1.20e\n",y0(1e300));
    		exit(0);
    	    }

        % cc example1.c libm.a
        % a.out
        y0: TLOSS error
        y0(1e300) = 0.00000000000000000000e+00

    It is possible to change the default standard in multi-standard
    fdlibm. Here is an example of how to do it:
        example2:
        ---------
    	#include "fdlibm.h"	/* must include FDLIBM's fdlibm.h */
    	main()
    	{
    		double y0();
    		_LIB_VERSION =  _IEEE_;
    		printf("IEEE: y0(1e300) = %1.20e\n",y0(1e300));
    		_LIB_VERSION = _XOPEN_;
    		printf("XOPEN y0(1e300) = %1.20e\n",y0(1e300));
    		_LIB_VERSION = _POSIX_;
    		printf("POSIX y0(1e300) = %1.20e\n",y0(1e300));
    		_LIB_VERSION = _SVID_;
    		printf("SVID  y0(1e300) = %1.20e\n",y0(1e300));
    		exit(0);
    	}

        % cc example2.c libm.a
        % a.out
          IEEE: y0(1e300) = -1.36813604503424810557e-151
          XOPEN y0(1e300) = 0.00000000000000000000e+00
          POSIX y0(1e300) = 0.00000000000000000000e+00
          y0: TLOSS error
          SVID  y0(1e300) = 0.00000000000000000000e+00

    Note:	Here _LIB_VERSION is a global variable. If global variables
    	are forbidden, then one should modify fdlibm.h to change
    	_LIB_VERSION to be a global constant. In this case, one
    	may not change the value of _LIB_VERSION as in example2.

    ---------------------------
    5. NOTES ON PORTING FDLIBM
    ---------------------------
    	Care must be taken when installing FDLIBM over existing
    	libm.a.
    	All co-existing function prototypes must agree, otherwise
    	users will encounter mysterious failures.

    	So far, the only known likely conflict is the declaration
    	of the IEEE recommended function scalb:

    		double scalb(double,double)	(1)	SVID3 defined
    		double scalb(double,int)	(2)	IBM,DEC,...

    	FDLIBM follows Sun definition and use (1) as default.
    	If one's existing libm.a uses (2), then one may raise
    	the flags _SCALB_INT during the compilation of FDLIBM
    	to get the correct function prototype.
    	(E.g., make "CFLAGS = -D_IEEE_LIBM -D_SCALB_INT".)
    	NOTE that if -D_SCALB_INT is raised, it won't be SVID3
    	conformant.

    --------------
    6. PROBLEMS ?
    --------------
    Please send comments and bug report to:
    		fdlibm-comments@sunpro.eng.sun.com