   Copyright (C)  2000    Daniel A. Atkinson  <DanAtk@aol.com>
   Copyright (C)  2004    Ivano Primi  <ivano.primi@tin.it>    

   Copying and distribution of this file, with or without modification,
   are permitted in any medium without royalty provided the copyright
   notice and this notice are preserved.

*******************************************************************************

                           HIGH PRECISION ARITHMETIC

                                   Summary

                 The extended precision library implements a high
                 precision floating point arithmetic together with a
                 comprehensive set of support functions. The general
                 areas covered by these functions include:

                     o Extended Precision Arithmetic
                     o Extended Precision Math Library
                     o Applications of High Precision Computation

                 The math library support includes evaluation of
                 trigonometric, inverse trigonometric, hyperbolic,
                 logarithm, and exponential functions at the same
                 precision as the floating point math itself.

-------------------------------------------------------------------------------

 Note on Contents

 o Extended Precision Floating Point Arithmetic:

    xadd  -------- add/subtract two extended precision numbers.
    xmul  -------- multiply two extended precision numbers.
    xdiv  -------- divide two extended precision numbers.
    xneg  -------- change sign (xneg), compute absolute value (xabs),
                   extract exponent (x_exp), and test sign (x_neg) of
                   an extended precision number.
    xpwr  -------- raise an extended precision number to an integer
                   power (xpwr), to an extended precision power (xpow), or 
		   multiply it by a power of 2 (xpr2).
    xprcmp  ------ compare two extended precision numbers.
    xtodbl  ------ convert an extended precision number to a double
                   (xtodbl), a double to extended precision (dbltox),
    xtoflt  ------ convert an extended precision number to a float
                   (xtoflt) or a float to an extended precision (flttox)
                   number.
    inttox ------- convert a 'long' (inttox) or an 'unsigned long' (uinttox)
		   to an extended precision number.
    xfmod  ------- analogs of standard library fmod (xfmod), and frexp
                   (xfrexp) functions.
    xfrac  ------- obtain the fractional (xfrac) or integer (xtrunc, xfix)
		   part of an extended precision number.
    xround ------- round an extended precision number to the nearest
		   integer value (halfway  cases  away  from zero).
    xceil  ------- obtain the smallest integral value not less than argument
	           (xceil) or the largest integral value not greater than
		   argument (xfloor).
    atox  -------- convert a numerical string to an extended precision
                   number.
    xpr_print ---- print an extended precision number in scientific
		   or floating point format onto a given file.
    xpr_asprint -- convert an extended precision number to a string.
    xbprint ------ print an extended precision number in binary format.
    xprxpr  ------ print an extended precision number in scientific
                   format, or print the binary format as a string of
                   hexadecimal short integers (xprint).
    xout --------- print an extended precision number on file (xfout),
		   on stdout (xout), or on string (xsout) according to
		   a given format.

     The arithmetic functions support the basic computation and input/output
 operations needed for extended precision floating point mathematics. Some
 of the operations supply capabilities designed to enhance the computational
 efficiency of this arithmetic (e.g., 'xpwr').
    
 o Extended Precision Math Library:

    xsqrt  ------- compute the square root of an extended precision
                   number.
    xexp  -------- extended precision exponential function (xexp),
	           base-2 exponential function (xexp2) and 
		   base-10 exponential function (xexp10).
    xlog  -------- extended precision natural logarithm (xlog), 
		   base-2 logarithm (xlog2) and base-10 logarithm (xlog10).
    xtrig  ------- extended precision sine (xsin), cosine (xcos),
                   and tangent (xtan) functions.
    xivtrg  ------ extended precision arcsine (xasin), arccosine
                   (xacos), and arctangent (xatan) functions.
    xhypb  ------- extended precision hyperbolic functions for
                   sinh (xsinh), cosh (xcosh), and tanh (xtanh).
    xivhypb ------ extended precision hyperbolic arcsine (xasinh), 
		   hyperbolic arccosine (xacosh), and arctangent 
		   (xatanh) functions.

     These functions provide the elementary function evaluations normally
 supported in a C math library. They are designed to provide full precision
 accuracy.
    
 o Applications of Extended Precision Arithmetic:

    xchcof  ------- compute extended precision Tchebycheff expansion
                    coefficients.
    xevtch  ------- evaluate an extended precision Tchebycheff series.

     The Tchebycheff expansion supplied with the library can be used to
 compute the Tchebycheff expansion coefficients of a function to an accuracy
 of 32 digits. This ability is useful in developing high accuracy function
 approximations, since the effect of rounding error on coefficients used in
 double precision can effectively be eliminated with these inputs.

-------------------------------------------------------------------------------

 General Technical Comments

     The full implementation of a floating point arithmetic is not commonly a
 component included in a mathematical utility library. This enhancement is
 included because we have found it invaluable in the analysis of problems that
 may originate with the floating point arithmetic. The functions are all
 implemented in a portable fashion in the C language.

     The IEEE 754 standard for floating point hardware and software is assumed
 in the PC version of this library. The normal configuration of the library
 employs a floating point mantissa of 112 bits, or approximately 32 decimal
 digit precision. However, even higher precision is available as an option.

     An extended floating point number is represented as a combination of the
 following elements:

                    sign bit(s): 0 -> positive, 1 -> negative ;
                    exponent(e): 15-bit biased integer (bias=16383) ;
                    mantissa(m): 7 words of 16 bit length with the
                                 leading 1 explicitly represented .

                   Thus  f = (-1)^s*2^[e-16383] *m ,  with 1 <= m < 2 .

 This format supports a dynamic range of:

                    2^16384 > f > 2^[-16383]  or

                    1.19*10^4932 > f > 1.68*10^-[4932].

 Special values of the exponent are:

                    all ones -> infinity (floating point overflow)
                    all zeros -> number = zero.

 Underflow in operations is handled by a flush to zero. Thus, a number with
 the exponent zero and nonzero mantissa is invalid (not-a-number).

-------------------------------------------------------------------------------

                          GENERAL OVERVIEW
-------------------------------------------------------------------------------

When I wrote the HPA library, I tried to create a sort of namespace
for all the identifiers used by the library.
This has been achieved by sticking to the following rules:

- The identifiers of functions and types are lowercase with the unique
exception of the function 'xisNaN()'. Their names start
by 'x', with the only exception of a few functions,
which however have a name ending by 'tox': 'strtox()',
'dbltox()', 'flttox()', 'inttox()', 'uinttox()', 'atox()';
- The names of the macros defined by the HPA library are all uppercase
and start by 'X';
- The names of the global constants defined by the HPA library start
by 'x' and the letter which immediately follows this prefix is always 
uppercase, just as in 'xZero', 'xPi';
- The unique global variable defined by the HPA library is an
error indicator of 'int' type, whose name is 'xErrNo'.

The header files for extended precision arithmetic is 'xpre.h'.
The 'xpre.h' file contains a definition of the basic structure of an 
extended precision number ('struct xpr'), and declarations
for the library functions. The header file 'xpre.h' must be included in 
order to use high precision arithmetic.
The header file 'xpre.h' defines several constants. Between the
constants defined in 'xpre.h' there are those ones
corresponding to particular mathematical values:

  extern const struct xpr xZero, xOne, xTwo, xTen;
  extern const struct xpr xPinf, xMinf, xNaN;
  extern const struct xpr xPi, xPi2, xPi4, xEe, xSqrt2;
  extern const struct xpr xLn2, xLn10, xLog2_e, xLog2_10, xLog10_e;

xZero (= 0), xOne (= 1), xTwo (= 2)and xTen (= 10) 
do not need a comment.
xPi, xPi2, xPi4, xEe, xSqrt2, xLn2, xLn10, xLog2_e, xLog2_10, xLog10_e
represent respectively the values PI (= 3.14159...), PI/2, PI/4,
e (= 2.7182818...), square root of 2 (= 1.4142135...), natural
logarithm of 2 and 10, base-2 logarithm of e and 10, 10-base
logarithm of e.

xPinf, xMinf and xNan are special values: xPinf represents the value
'+oo' (plus infty), xMinf the value '-oo' (minus infty) and xNaN
is used to mean an invalid number (NaN stays for Not a Number).
xPinf and xMinf are usually returned by a function to signal a
floating point overflow (positive and negative respectively), while
xNaN is returned by the functions converting ASCII strings to floating
point numbers to indicate that the string given to them as argument
did not contain any valid number.
xPinf, xMinf and xNaN should never be used as arguments for functions,
since a such use has unpredictable results.

The header file 'xpre.h' also defines the structure 'xoutflags':

  struct xoutflags
  {
    short fmt, notat, sf, mfwd, lim;
    signed char padding, ldel, rdel;
  };

A structure of such kind is used by the output functions
xfout(), xout() and xsout() to know how they have to print the 
numbers. 

The field 'notat' refers to the notation: it can
be equal to XOUT_SCIENTIFIC (scientific notation) or to XOUT_FIXED
(floating point notation). Both XOUT_SCIENTIFIC and XOUT_FIXED are
macros defined inside 'xpre.h'.

The field 'sf' refers to the sign: when 'sf' is not zero every non-negative
number is printed with a plus sign (+) ahead.

The field 'mfwd' indicates the minimum field width to use in
printing numbers. When 'mfwd' is zero no minimum field width is used.
When 'mfwd' is negative, then the actual minimum field width is given
by -mfwd and the printed number is left adjusted on the
field boundary. (The default is right justification).

'lim' has a different meaning depending on the actual notation in use.
Together with the scientific notation, 'lim' gives the number of 
decimal digits to the right of the decimal point 
(lim+1=total digits displayed). Otherwise, 'lim + 1' is the
number of significant digits displayed. When 'lim' is negative,
the default value (6) is used.

At last, 'padding' defines the padding character to use together
with a non-zero minimum field width.
If 'padding' is negative, then the default padding char (i.e. the
blank character) is used.

The fields 'fmt', 'ldel' and 'rdel' are ignored by the functions
xfout(), xout() and xsout(). They will only be used by the complex
printing functions cxfout(), cxout() and cxsout().

Be careful ! None of the functions 'xfout()', 'xout()' or 'xsout()'
adds a newline at the end of the printed number !

A last note: the HPA library is **NOT** thread safe. Some of the HPA internal
data could get corrupted if multiple HPA functions are active at the
same time. This is due to the fact that some functions of the HPA library
use static variables to store information.
So, the user should guarantee that only one thread is performing
HPA functions. This can usually be achieved by a call to the operating
system to obtain a "semaphore", "mutex",  or "critical code section" so
the operating system will guarantee that only one HPA thread will be
active at a time.


-------------------------------------------------------------------------------

    Dealing with errors
-------------------------------------------------------------------------------

See file hpa.txt in the 'doc' directory of the HPA library
(probably the same where you found this file).

-------------------------------------------------------------------------------

                          FUNCTION SYNOPSES
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------

     Basic Operations:
-------------------------------------------------------------------------------

xadd

     Add (subtract) two extended precision numbers.

     struct xpr xadd(struct xpr s,struct xpr t,int f)
       s = structure containing first number
       t = structure containing second number
       f = control flag, with 0 -> add inputs (s+t)
                              1 -> subtract inputs (s-t)
      return value: x = structure containing result

-------------------------------------------------------------------------------

xmul

     Multiply two extended precision numbers.

     struct xpr xmul(struct xpr s,struct xpr t)
       s = structure containing first number
       t = structure containing second number
      return value: x = structure containing product (x=s*t)

-------------------------------------------------------------------------------

xdiv

     Divide one extended precision number by a second.

     struct xpr xdiv(struct xpr s,struct xpr t)
       s = structure containing numerator
       t = structure containing denominator
      return value: x = structure containing quotient (x=s/t)

-------------------------------------------------------------------------------

     Useful Floating Point Operations:
-------------------------------------------------------------------------------

xneg

     Functions to change sign (unary minus), compute absolute value,
     extract the exponent, and test the sign of an extended precision
     number.

     struct xpr xneg(struct xpr s)
       s = structure containing input number
      return value: x = structure containing negative of input (x= -s)

-------------------------------------------------------------------------------

xabs

     struct xpr xabs(struct xpr s)
     struct xpr s;
       s = structure containing input number
      return value: x = structure containing absolute value of s

-------------------------------------------------------------------------------

x_exp
  
     int x_exp (struct xpr *p)

       p = pointer to an extended precision number
      return value: e = exponent (power of 2) of the input number

-------------------------------------------------------------------------------

x_neg

     int x_neg(struct xpr *p)

       p = pointer to an extended precision number
      return value: s = sign flag, with
                        0 -> positive input
                        1 -> negative input

 
       Note that x_exp and x_neg do not alter the input number!

-------------------------------------------------------------------------------

xpwr

     Functions for integer powers and multiplication by a power of two.

     struct xpr xpwr(struct xpr s,int n)
       s = structure containing input number
       n = power desired
      return value: x = structure containing nth power of input (s)^n.

-------------------------------------------------------------------------------

xpr2

     struct xpr xpr2(struct xpr s,int m)
       s = structure containing input number
       m = power of two desired
      return value: x = structure containing product s*2^m.

-------------------------------------------------------------------------------

xpow

      Power function

      struct xpr xpow (struct xpr x, struct xpr y)
	
        x = base
        y = exponent
      return value : p = structure containing x^y	

      Note that x must be positive.

-------------------------------------------------------------------------------

xprcmp

     Compare two extended precision numbers.

     int xprcmp (const struct xpr *p, const struct xpr *q)
       p = pointer to first number
       q = pointer to second number
      return value: comparison flag, with
                     1 -> *p > *q
                     0 -> *p = *q
                    -1 -> *p < *q

      The input numbers are not altered by xprcmp!

-------------------------------------------------------------------------------

xis0
     Compare a number with 0 

     int xis0 (struct xpr x)

      x = structure containing function argument

     return value: 0 if x is not zero, else a non-zero value.

-------------------------------------------------------------------------------

xnot0

     Compare a number with 0 

     int xnot0 (struct xpr x)

      x = structure containing function argument

     return value: 0 if x is zero, else a non-zero value.

-------------------------------------------------------------------------------

xeq

     Check if two numbers are or are not equal

     int xeq (struct xpr x1, struct xpr x2)

      x1 = first argument
      x2 = second argument

     return value: 0 if x1 and x2 are different, else a
                   non-null value.

-------------------------------------------------------------------------------

xneq

     Check if two numbers are or are not equal

     int xneq (struct xpr x1, struct xpr x2)

      x1 = first argument
      x2 = second argument

     return value: 0 if x1 and x2 are equal, else a
                   non-null value.

-------------------------------------------------------------------------------

xgt

     Check if a number is greater than another one

     int xgt (struct xpr x1, struct xpr x2)  

      x1 = first argument
      x2 = second argument

     return value: 0 if x1 <= x2, else a non-null value.

-------------------------------------------------------------------------------

xge

     Check if a number is greater or equal to another one

     int xge (struct xpr x1, struct xpr x2)  

      x1 = first argument
      x2 = second argument

     return value: 0 if x1 < x2, else a non-null value.

-------------------------------------------------------------------------------

xlt

     Check if a number is less than another one

     int xlt (struct xpr x1, struct xpr x2)  

      x1 = first argument
      x2 = second argument

     return value: 0 if x1 >= x2, else a non-null value.

-------------------------------------------------------------------------------

xle

     Check if a number is less or equal to another one

     int xle (struct xpr x1, struct xpr x2)  

      x1 = first argument
      x2 = second argument

     return value: 0 if x1 > x2, else a non-null value.

-------------------------------------------------------------------------------

xisNaN

     Comparison with xNaN

     int xisNaN (const struct xpr *u)

      u = pointer to a structure containing a number

     return value: 0 if *u is different from xNaN, else
                   a non-null value.

-------------------------------------------------------------------------------

xtodbl

     Convert doubles to extended precision and cast
     extended precision numbers to doubles.

     double xtodbl(struct xpr s)
       s = structure containing extended precision input
      return value: x = double precision float = s

     struct xpr dbltox(double y)
       y = double precision floating point input
      return value: x = structure containing extended equivalent (x=y)

-------------------------------------------------------------------------------

xtoflt

     Convert floats to extended precision and cast
     extended precision numbers to floats.

     float xtoflt(struct xpr s)
       s = structure containing extended precision input
      return value: x = single precision float = s

     struct xpr flttox(float y)
       y = single precision floating point input
      return value: x = structure containing extended equivalent (x=y)

-------------------------------------------------------------------------------

inttox

     Convert integers, signed (inttox) and unsigned (uinttox),
     to extended precision numbers.

     struct xpr inttox(long n)
       n = integer input
      return value: x = structure containing extended equivalent (x=n)

     struct xpr uinttox(unsigned long n)
       n = integer input
      return value: x = structure containing extended equivalent (x=n)

-------------------------------------------------------------------------------

xfmod

     These functions are extended precision analogs of the standard library
     fmod and frexp functions.
     
     struct xpr xfmod(struct xpr s,struct xpr t,struct xpr* q)
       s = structure containing operand of fmod
       t = structure containing base number (t!=0)
       q = pointer to store for output integer m
      return value: x = structure of extended number with same sign as s
                        and absolute value less than that of t, satisfying
                         s = m*t + x  if s*t>0, or
                         s = -m*t +x  if s*t<0

-------------------------------------------------------------------------------

xfrexp

     struct xpr xfrexp(struct xpr s,int *p)
       s = structure containing operand
       p = pointer to store for output exponent e
      return value: x = structure of extended number satisfying
                        x = s*2^(-e)  with  (-1 < x <1).

-------------------------------------------------------------------------------

xfrac

     Obtain the fractional part of a number.

     struct xpr xfrac  (struct xpr s)
       s = structure containing operand
      return value: fractional part of the number 's' with
                    the same sign as 's'.

     Remark:

     The fractional part of the number 's' is 0 if 's' is an
     integer number, else it is given by (-)0.xyz...,  where 
     xyz...  are the digits of 's' following the radix character
     (".") in the decimal representation. xfrac(s) has always
     the same sign as 's'.

-------------------------------------------------------------------------------

xtrunc

     Obtain the integer part of a number.

     struct xpr xtrunc  (struct xpr s)
       s = structure containing operand
      return value: integer part of the number 's' with
                    the same sign as 's'.

     Remark:

     The integer part of the number 's' is given by  (-)xyz...,  where 
     xyz...  are the digits of 's' before the radix character (".") in
     its decimal representation.

-------------------------------------------------------------------------------

xfix

     Obtain the integer part of a number (2nd method).

     struct xpr xfix  (struct xpr s)

     Remark:

     xfix() is provided as an alternative to xtrunc(). xfix() tries
     to take into account possible rounding errors and cancel their
     effects. The use of xfix() is strongly suggested whenever the argument
     is presumed to be an integer number, but it is reasonable to expect 
     that some rounding errors make its actual value a bit different from 
     that one it should be.
     For instance, when sizeof(struct xpr) == 64, on my machine I
     obtain

	xtrunc (xdiv (inttox(100), inttox(100))) == xZero

     while one could expect xOne as result. This happens since
     xdiv (inttox(100), inttox(100)) returns a number a bit lower
     than 1. On the other hand

	xfix (xdiv (inttox(100), inttox(100))) == xOne .

     Care that xfix() introduces another type of rounding error
     to give the correct answer in the cases similar to the previous
     one. So, it is not always the right choice. :) 


-------------------------------------------------------------------------------

xround

     Round an extended precision number to its nearest integer value
     (halfway cases are rounded away from zero). 

     struct xpr xround  (struct xpr s)
       s = structure containing operand
      return value: the integer value nearest to s


-------------------------------------------------------------------------------

xceil

     Ceiling function: smallest integral value not less than argument

     struct xpr xceil  (struct xpr s)
       s = structure containing operand
      return value: smallest integral value not less than s.


-------------------------------------------------------------------------------

xfloor

     Largest integral value not greater than argument

     struct xpr xfloor  (struct xpr s)
       s = structure containing operand
      return value: largest integral value not greater than s

-------------------------------------------------------------------------------

strtox

     Convert a floating point number, expressed as a decimal ASCII string
     in a form consistent with C, into the extended precision format.

     struct xpr strtox (const char* s, char** endptr)
       s = pointer to null terminated ASCII string expressing a
           decimal number
       endptr = NULL or address of a pointer to char defined
                outside strtox() 
      return value: u = structure containing input number in the
                         extended precision format.

     Remark:

     The strtox() function converts the initial portion of the string pointed to
     by 's' to its extended precision representation.

     The  expected  form  of  the (initial portion of the) string is optional
     leading white space  as  recognized  by  isspace(3),  an  optional  plus
     ("+")  or  minus sign ("-") and then a decimal number.

     A  decimal number consists of a nonempty sequence of decimal digits pos
     sibly containing a radix character (decimal  point, i.e. "."), optional-
     ly  followed by a decimal exponent.   A decimal exponent consists of an 
     "E" or "e", followed by an optional plus  or minus  sign,  followed  by  
     a non-empty sequence of decimal digits, and indicates multiplication by 
     a power of 10.

     This function returns the converted value, if any.

     If 'endptr' is not NULL, a pointer to the character after the last charac
     ter  used  in  the  conversion  is  stored in the location referenced by
     'endptr'.

     If no conversion is performed, 'xNaN' is returned and the value of 's' is
     stored in the location referenced by 'endptr'.

     If  the  correct  value  would  cause  overflow, then 'xPinf' 
     or 'xMinf' is returned, according to the sign of the value.
     If the correct value would cause underflow, 'zero' is returned.

-------------------------------------------------------------------------------

atox

     Convert a floating point number, expressed as a decimal ASCII string
     in a form consistent with C, into the extended precision format.

     struct xpr atox(const char *s)
       s = pointer to null terminated ASCII string expressing a
           decimal number
      return value: u = structure containing input number in the
                         extended precision format.

     Remark:

     The call  atox(s)  is equivalent to  strtox(s, NULL) .

-------------------------------------------------------------------------------

xpr_print

     Print an extended precision number in scientific or floating point format
     onto a given file.

     void  xpr_print (FILE* stream, struct xpr u, int sc_not, int sign, int lim)
       stream = file where the number must be printed
       u = structure containing number to be printed
       sc_not = zero to mean floating point format, not zero to mean
                scientific format
       sign   = not zero to put a plus sign (+) before the number if
                it is non-negative (in case of negative number a
                minus sign (-) is always printed even if the
                parameter 'sign' is zero) 	
       lim = number of decimal digits to the right of the
             decimal point (lim+1=total digits displayed) in
             case of scientific format, else number of
             significant digits - 1 (lim+1=total of significant
             digits).

-------------------------------------------------------------------------------

xpr_asprint

     Convert an extended precision number to a string.

     char* xpr_asprint (struct xpr u, int sc_not, int sign, int lim)
       u = structure containing number to be printed
       sc_not = zero to mean floating point format, not zero to mean
                scientific format
       sign   = not zero to put a plus sign (+) before the number if
                it is non-negative (in case of negative number a
                minus sign (-) is always printed even if the
                parameter 'sign' is zero) 	
       lim = number of decimal digits to the right of the
             decimal point (lim+1=total digits displayed) in
             case of scientific format, else number of
             significant digits - 1 (lim+1=total of significant
             digits).

     Remark:

     xpr_asprint() returns the string with the converted number.
     The memory for this string is calloc'ed inside the function.

-------------------------------------------------------------------------------

xprxpr

     Print an extended precision number in scientific format.

     void xprxpr(struct xpr u,int lim)
       u = structure containing number to be printed
       lim = number of decimal digits to the right of the
             decimal point (lim+1=total digits displayed)

     Remark:

     xprxpr(u, lim)
 
       is equivalent to  

     xpr_print(stdout, u, 1, 0, lim)

-------------------------------------------------------------------------------

xfout

     Print an extended precision number on file according to
     a given set of I/O flags.

     int xfout (FILE * stream, struct xoutflags ofs, struct xpr x)
       stream = file where the number must be printed
       ofs = structure containing all the I/O flags
       x = structure containing number to be printed
       return value: 0 in case of success, -1 to mean
		     a failure
     

     Remark: For the definition of 'struct xoutflags' and the meaning 
	     of its fields see above. 
	     xfout() does not add any newline at the end of
	     the printed number.
     
-------------------------------------------------------------------------------

xout

     Print an extended precision number on stdout according to
     a given set of I/O flags.

     int xout (struct xoutflags ofs, struct xpr x)
       ofs = structure containing all the I/O flags
       x = structure containing number to be printed
       return value: 0 in case of success, -1 to mean
		     a failure
     

     Remark: For the definition of 'struct xoutflags' and the meaning 
	     of its fields see above. 
	     xout() does not add any newline at the end of
	     the printed number.
     
-------------------------------------------------------------------------------

xsout

     Write an extended precision number on a string according to
     a given set of I/O flags.

     int xsout (char* s, unsigned long n, struct xoutflags ofs, struct xpr x)
       s = pointer to a buffer of characters (char)
       n = size of the buffer
       ofs = structure containing all the I/O flags
       x = structure containing number to be printed
       return value: m = number of the non-null characters written
	                 to the buffer or, if m >= n, which
			 would have been written to the buffer 
			 if enough space had  been available. 

     Remark: For the definition of 'struct xoutflags' and the meaning 
	     of its fields see above. 
	     xsout() always adds a null character ('\0') at the end of
	     the written number.
             xsout() does not write more than 'n' bytes (including
             the  trailing  '\0'). Thus, a return value of 'n' or more
	     means that the output was truncated. In this case,
	     the contents of the buffer pointed to by the first
	     argument of xsout() are COMPLETELY unreliable.
              

-------------------------------------------------------------------------------

xtoa

     Convert an extended precision number to a string.

     char* xtoa (struct xpr u,int lim)
       u = structure containing number to be printed
       lim = number of decimal digits to the right of the
             decimal point (lim+1=total digits displayed) in
             case of scientific format, else number of
             significant digits - 1 (lim+1=total of significant
             digits).

     Remark:

     xtoa() returns the string with the converted number.
     The memory for this string is calloc'ed inside the function.
     Moreover,

     xtoa(u, lim) 
     
     is equivalent to

     xpr_asprint (u, 1, 0, lim)

-------------------------------------------------------------------------------

xbprint

     Print an extended precision number in binary format.

     void xbprint (FILE* stream, struct xpr u)
       stream = file where the number must be printed
       u = structure containing number to be printed

     The 'xbprint' function supports a bit oriented analysis of
     rounding error effects. It always prints a newline ('\n')
     at the end of the binary string.

-------------------------------------------------------------------------------

xprint

     Print an extended precision number as a string of hexadecimal
     numbers.

       void xprint(FILE* stream, struct xpr u)
       stream = file where the number must be printed
       u = structure containing number to be printed


     The 'xprint' function supports a bit oriented analysis of
     rounding error effects. It always prints a newline ('\n')
     at the end.

-------------------------------------------------------------------------------

     Auxiliary Functions Supporting High Precision Math:
------------------------------------------------------------------------------- 

     These routines support functions in the high precision library.
     They are not normally called by a user.

xsfmod

     Special modular function to extract integer part of a number.

     struct xpr xsfmod(struct xpr s,int *p)
       s = structure containing input number
       p = pointer to store for integer part of s
           ( *p= -1 -> integer part > 2^15 , overflow)
      return value: u = structure containing fractional part of s

-------------------------------------------------------------------------------

shift

     Functions to shift the bits of extended precision structures
     left/right.

     void xlshift(int n,unsigned short *pm,int m)
       pm = pointer to initial word to be shifted
             (output left shifted n bits and zero filled
              on the right)
       n = number of bits to left-shift
       m = number of words in shift structure

     void xrshift(int n,unsigned short *pm,int m)
       pm = pointer to initial word to be shifted
             (output right shifted n bits and zero filled
              on the left)
       n = number of bits to right-shift
       m = number of words in shift structure


      The m-word structures pointed to by pm are changed
       by the shift functions!

-------------------------------------------------------------------------------

     Extended Precision Math Library:
-------------------------------------------------------------------------------

xsqrt

     Compute the square root of an extended precision number.

     struct xpr xsqrt(struct xpr z)
        z = structure containing the input number (z>=0)
      return value: x = structure containing square root of input

          Input of a negative argument results in an error.

-------------------------------------------------------------------------------

xexp

     Compute the exponential function.

     struct xpr xexp(struct xpr z)
        z = structure containing function argument
      return value: structure x = exp(z)

-------------------------------------------------------------------------------

xexp2

     Compute the base-2 exponential function.

     struct xpr xexp2(struct xpr z)
        z = structure containing function argument
      return value: structure x = 2^(z)

-------------------------------------------------------------------------------

xexp10

     Compute the base-10 exponential function.

     struct xpr xexp10(struct xpr z)
        z = structure containing function argument
      return value: structure x = 10^(z)

-------------------------------------------------------------------------------

xlog

     Compute natural (base e) logarithms.

     struct xpr xlog(struct xpr z)
        z = structure containing function argument (z>0)
      return value: structure x = log(z)

          Input of z<=0 results in an error.

-------------------------------------------------------------------------------

xlog2

     Compute base-2 logarithms.

     struct xpr xlog2(struct xpr z)
        z = structure containing function argument (z>0)
      return value: structure x = log_2(z)

          Input of z<=0 results in an error.

-------------------------------------------------------------------------------

xlog

     Compute base-10 logarithms.

     struct xpr xlog10(struct xpr z)
        z = structure containing function argument (z>0)
      return value: structure x = log_10(z)

          Input of z<=0 results in an error.

-------------------------------------------------------------------------------

xtrig

xtan

     Compute the trigonometric functions tan, cos, and sin.

     struct xpr xtan(struct xpr z)
        z = structure containing function argument
      return value: structure f = tan(z)

     Remark: xtan(z) returns xPinf when z is equal to xPi2
	     (up to an integer multiple of xPi),
             xMinf when z is equal to -xPi2 (up to an
	     integer multiple of xPi). In both cases an
             Out-of-domain error is produced.

-------------------------------------------------------------------------------

xcos

     struct xpr xcos(struct xpr z)
        z = structure containing function argument
      return value: structure f = cos(z)

-------------------------------------------------------------------------------

xsin

     struct xpr xsin(struct xpr z)
        z = structure containing function argument
      return value: structure f = sin(z)

-------------------------------------------------------------------------------

xivtrg

     Compute the inverse trigonometric functions.

xatan

     struct xpr xatan(struct xpr z)
        z = structure containing function argument
      return value: structure f = atan(z) (-Pi/2 <= f <= Pi/2)

xasin

     struct xpr xasin(struct xpr z)
        z = structure containing function argument (|z|<=1)
      return value: structure f = asin(z) (-Pi/2 <= f <= Pi/2)

xacos

     struct xpr xacos(struct xpr z)
        z = structure containing function argument (|z|<=1)
      return value: structure f = acos(z) (0 <= f <= Pi)

     Remark:

            Out-of-range values of z in xasin and xacos will produce
            an error.

-------------------------------------------------------------------------------

xhypb

     Compute the hyperbolic functions tanh, sinh, and cosh.

xtanh

     struct xpr xtanh(struct xpr z)
        z = structure containing function argument
      return value: structure f = tanh(z)

-------------------------------------------------------------------------------

xsinh

     struct xpr xsinh(struct xpr z)
        z = structure containing function argument
      return value: structure f = sinh(z)

-------------------------------------------------------------------------------

xcosh

     struct xpr xcosh(struct xpr z)
        z = structure containing function argument
      return value: structure f = cosh(z)


-------------------------------------------------------------------------------

xivhypb

     Compute the inverse hyperbolic functions atanh, asinh, and acosh.

xatanh

     struct xpr xatanh(struct xpr z)
        z = structure containing function argument
      return value: structure f = atanh(z)

-------------------------------------------------------------------------------

xasinh

     struct xpr xasinh(struct xpr z)
        z = structure containing function argument
      return value: structure f = asinh(z)

-------------------------------------------------------------------------------

xacosh

     struct xpr xacosh(struct xpr z)
        z = structure containing function argument
      return value: structure f = acosh(z)

     Remark:

            Out-of-range values of z in xacosh and xatanh will
	    produce an error.

-------------------------------------------------------------------------------


     Extended Precision Applications:
-------------------------------------------------------------------------------

xchcof

     Compute the Tchebycheff expansion coefficients of a specified function.

     xchcof(struct xpr *c,int m,struct xpr (*xfunc)(struct xpr))
        c = pointer to array of extended precision structures for
            computed coefficients
        m = maximum index of coefficient array (dimension=m+1)
        xfunc = pointer to user defined function returning extended
                 precision values of the function f

                 f(x) = c[0]/2 + Sum(k=1 to m) c[k]*Tk(x) , with

                 Tk(x) the kth  Tchebycheff polynomial.

-------------------------------------------------------------------------------

xevtch

     Evaluate an extended precision Tchebycheff expansion.

     struct xpr xevtch(struct xpr z,struct xpr *a,int m)
        z = structure containing function argument
        a = structure array containing expansion coefficients
        m = maximum index of coefficient array (dimension=m+1)
      return value: function value f, with

                 f(x) = Sum(k=0 to m) a[k]*Tk(x) .
