expm1.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:6k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* expm1.c - math routines */
  2. /* Copyright 1992 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01c,20sep92,smb  documentation additions.
  7. 01b,30jul92,kdl  marked routine NOMANUAL.
  8. 01a,08jul92,smb  documentation.
  9. */
  10. /*
  11. DESCRIPTION
  12. *
  13. * This file includes a support routine (expm1()) which is used by
  14. * other portions of the UCB ANSI C library.
  15. *
  16. * Copyright (c) 1985 Regents of the University of California.
  17. * All rights reserved.
  18. *
  19. * Redistribution and use in source and binary forms are permitted
  20. * provided that the above copyright notice and this paragraph are
  21. * duplicated in all such forms and that any documentation,
  22. * advertising materials, and other materials related to such
  23. * distribution and use acknowledge that the software was developed
  24. * by the University of California, Berkeley.  The name of the
  25. * University may not be used to endorse or promote products derived
  26. * from this software without specific prior written permission.
  27. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  28. * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  29. * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  30. *
  31. * All recipients should regard themselves as participants in an ongoing
  32. * research project and hence should feel obligated to report their
  33. * experiences (good or bad) with these elementary function codes, using
  34. * the sendbug(8) program, to the authors.
  35. *
  36. * SEE ALSO: American National Standard X3.159-1989
  37. *
  38. * NOMANUAL
  39. */
  40. #include "vxWorks.h"
  41. #include "math.h"
  42. #if defined(vax)||defined(tahoe) /* VAX D format */
  43. #ifdef vax
  44. #define _0x(A,B) 0x/**/A/**/B
  45. #else /* vax */
  46. #define _0x(A,B) 0x/**/B/**/A
  47. #endif /* vax */
  48. /* static double */
  49. /* ln2hi  =  6.9314718055829871446E-1    , Hex  2^  0   *  .B17217F7D00000 */
  50. /* ln2lo  =  1.6465949582897081279E-12   , Hex  2^-39   *  .E7BCD5E4F1D9CC */
  51. /* lnhuge =  9.4961163736712506989E1     , Hex  2^  7   *  .BDEC1DA73E9010 */
  52. /* invln2 =  1.4426950408889634148E0     ; Hex  2^  1   *  .B8AA3B295C17F1 */
  53. static long     ln2hix[] = { _0x(7217,4031), _0x(0000,f7d0)};
  54. static long     ln2lox[] = { _0x(bcd5,2ce7), _0x(d9cc,e4f1)};
  55. static long    lnhugex[] = { _0x(ec1d,43bd), _0x(9010,a73e)};
  56. static long    invln2x[] = { _0x(aa3b,40b8), _0x(17f1,295c)};
  57. #define    ln2hi    (*(double*)ln2hix)
  58. #define    ln2lo    (*(double*)ln2lox)
  59. #define   lnhuge    (*(double*)lnhugex)
  60. #define   invln2    (*(double*)invln2x)
  61. #else /* defined(vax)||defined(tahoe) */
  62. static double
  63. ln2hi  =  6.9314718036912381649E-1    , /*Hex  2^ -1   *  1.62E42FEE00000 */
  64. ln2lo  =  1.9082149292705877000E-10   , /*Hex  2^-33   *  1.A39EF35793C76 */
  65. lnhuge =  7.1602103751842355450E2     , /*Hex  2^  9   *  1.6602B15B7ECF2 */
  66. invln2 =  1.4426950408889633870E0     ; /*Hex  2^  0   *  1.71547652B82FE */
  67. #endif /* defined(vax)||defined(tahoe) */
  68. /*****************************************************************************
  69. * expm1 -
  70. *
  71. * EXPM1(X)
  72. * RETURN THE EXPONENTIAL OF X MINUS ONE
  73. * DOUBLE PRECISION (IEEE 53 BITS, VAX D FORMAT 56 BITS)
  74. * CODED IN C BY K.C. NG, 1/19/85;
  75. * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/21/85, 4/16/85.
  76. *
  77. * Required system supported functions:
  78. * scalb(x,n)
  79. * copysign(x,y)
  80. * finite(x)
  81. *
  82. * Kernel function:
  83. * exp__E(x,c)
  84. *
  85. * Method:
  86. * 1. Argument Reduction: given the input x, find r and integer k such
  87. *    that
  88. *                    x = k*ln2 + r,  |r| <= 0.5*ln2 .
  89. *    r will be represented as r := z+c for better accuracy.
  90. *
  91. * 2. Compute EXPM1(r)=exp(r)-1 by
  92. *
  93. * EXPM1(r=z+c) := z + exp__E(z,c)
  94. *
  95. * 3. EXPM1(x) =  2^k * ( EXPM1(r) + 1-2^-k ).
  96. *
  97. *  Remarks:
  98. *    1. When k=1 and z < -0.25, we use the following formula for
  99. *       better accuracy:
  100. * EXPM1(x) = 2 * ( (z+0.5) + exp__E(z,c) )
  101. *    2. To avoid rounding error in 1-2^-k where k is large, we use
  102. * EXPM1(x) = 2^k * { [z+(exp__E(z,c)-2^-k )] + 1 }
  103. *       when k>56.
  104. *
  105. * Special cases:
  106. * EXPM1(INF) is INF, EXPM1(NaN) is NaN;
  107. * EXPM1(-INF)= -1;
  108. * for finite argument, only EXPM1(0)=0 is exact.
  109. *
  110. * Accuracy:
  111. * EXPM1(x) returns the exact (exp(x)-1) nearly rounded. In a test run with
  112. * 1,166,000 random arguments on a VAX, the maximum observed error was
  113. * .872 ulps (units of the last place).
  114. *
  115. * Constants:
  116. * The hexadecimal values are the intended ones for the following constants.
  117. * The decimal values may be used, provided that the compiler will convert
  118. * from decimal to binary accurately enough to produce the hexadecimal values
  119. * shown.
  120. *
  121. * NOMANUAL
  122. */
  123. double expm1(x)
  124. double x;
  125. {
  126. static double one=1.0, half=1.0/2.0;
  127. double scalb(), copysign(), exp__E(), z,hi,lo,c;
  128. int k,finite();
  129. #if defined(vax)||defined(tahoe)
  130. static prec=56;
  131. #else /* defined(vax)||defined(tahoe) */
  132. static prec=53;
  133. #endif /* defined(vax)||defined(tahoe) */
  134. #if !defined(vax)&&!defined(tahoe)
  135. if(x!=x) return(x); /* x is NaN */
  136. #endif /* !defined(vax)&&!defined(tahoe) */
  137. if( x <= lnhuge ) {
  138. if( x >= -40.0 ) {
  139.     /* argument reduction : x - k*ln2 */
  140. k= invln2 *x+copysign(0.5,x); /* k=NINT(x/ln2) */
  141. hi=x-k*ln2hi ;
  142. z=hi-(lo=k*ln2lo);
  143. c=(hi-z)-lo;
  144. if(k==0) return(z+exp__E(z,c));
  145. if(k==1)
  146.     if(z< -0.25)
  147. {x=z+half;x +=exp__E(z,c); return(x+x);}
  148.     else
  149. {z+=exp__E(z,c); x=half+z; return(x+x);}
  150.     /* end of k=1 */
  151. else {
  152.     if(k<=prec)
  153.       { x=one-scalb(one,-k); z += exp__E(z,c);}
  154.     else if(k<100)
  155.       { x = exp__E(z,c)-scalb(one,-k); x+=z; z=one;}
  156.     else
  157.       { x = exp__E(z,c)+z; z=one;}
  158.     return (scalb(x+z,k));
  159. }
  160. }
  161. /* end of x > lnunfl */
  162. else
  163.      /* expm1(-big#) rounded to -1 (inexact) */
  164.      if(finite(x))
  165.  { ln2hi+ln2lo; return(-one);}
  166.      /* expm1(-INF) is -1 */
  167.      else return(-one);
  168. }
  169. /* end of x < lnhuge */
  170. else
  171. /*  expm1(INF) is INF, expm1(+big#) overflows to INF */
  172.     return( finite(x) ?  scalb(one,5000) : x);
  173. }