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

VxWorks

开发平台:

C/C++

  1. /* log1p.c - math routines */
  2. /* Copyright 1992 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01b,30jul92,kdl  marked routine NOMANUAL.
  7. 01a,08jul92,smb  documentation.
  8. */
  9. /*
  10. * DESCRIPTION
  11. *
  12. * This file includes a support routine (log1p()) which is used by
  13. * other portions of the UCB ANSI C library.
  14. *
  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. * #ifndef lint
  37. * static char sccsid[] = "@(#)log1p.c 5.3 (Berkeley) 6/30/88";
  38. * #endif * not lint *
  39. * SEE ALSO: American National Standard X3.159-1989
  40. * NOMANUAL
  41. */
  42. #include "vxWorks.h"
  43. #include "math.h"
  44. #if defined(vax)||defined(tahoe) /* VAX D format */
  45. #include <errno.h>
  46. #ifdef vax
  47. #define _0x(A,B) 0x/**/A/**/B
  48. #else /* vax */
  49. #define _0x(A,B) 0x/**/B/**/A
  50. #endif /* vax */
  51. /* static double */
  52. /* ln2hi  =  6.9314718055829871446E-1    , Hex  2^  0   *  .B17217F7D00000 */
  53. /* ln2lo  =  1.6465949582897081279E-12   , Hex  2^-39   *  .E7BCD5E4F1D9CC */
  54. /* sqrt2  =  1.4142135623730950622E0     ; Hex  2^  1   *  .B504F333F9DE65 */
  55. static long     ln2hix[] = { _0x(7217,4031), _0x(0000,f7d0)};
  56. static long     ln2lox[] = { _0x(bcd5,2ce7), _0x(d9cc,e4f1)};
  57. static long     sqrt2x[] = { _0x(04f3,40b5), _0x(de65,33f9)};
  58. #define    ln2hi    (*(double*)ln2hix)
  59. #define    ln2lo    (*(double*)ln2lox)
  60. #define    sqrt2    (*(double*)sqrt2x)
  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. sqrt2  =  1.4142135623730951455E0     ; /*Hex  2^  0   *  1.6A09E667F3BCD */
  66. #endif /* defined(vax)||defined(tahoe) */
  67. /**************************************************************************
  68. * log1p -
  69. *
  70. * LOG1P(x)
  71. * RETURN THE LOGARITHM OF 1+x
  72. * DOUBLE PRECISION (VAX D FORMAT 56 bits, IEEE DOUBLE 53 BITS)
  73. * CODED IN C BY K.C. NG, 1/19/85;
  74. * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/24/85, 4/16/85.
  75. *
  76. * Required system supported functions:
  77. * scalb(x,n)
  78. * copysign(x,y)
  79. * logb(x)
  80. * finite(x)
  81. *
  82. * Required kernel function:
  83. * log__L(z)
  84. *
  85. * Method :
  86. * 1. Argument Reduction: find k and f such that
  87. * 1+x  = 2^k * (1+f),
  88. *    where  sqrt(2)/2 < 1+f < sqrt(2) .
  89. *
  90. * 2. Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
  91. *  = 2s + 2/3 s**3 + 2/5 s**5 + .....,
  92. *    log(1+f) is computed by
  93. *
  94. *       log(1+f) = 2s + s*log__L(s*s)
  95. *    where
  96. * log__L(z) = z*(L1 + z*(L2 + z*(... (L6 + z*L7)...)))
  97. *
  98. *    See log__L() for the values of the coefficients.
  99. *
  100. * 3. Finally,  log(1+x) = k*ln2 + log(1+f).
  101. *
  102. * Remarks 1. In step 3 n*ln2 will be stored in two floating point numbers
  103. *    n*ln2hi + n*ln2lo, where ln2hi is chosen such that the last
  104. *    20 bits (for VAX D format), or the last 21 bits ( for IEEE
  105. *    double) is 0. This ensures n*ln2hi is exactly representable.
  106. * 2. In step 1, f may not be representable. A correction term c
  107. *      for f is computed. It follows that the correction term for
  108. *    f - t (the leading term of log(1+f) in step 2) is c-c*x. We
  109. *    add this correction term to n*ln2lo to attenuate the error.
  110. *
  111. *
  112. * Special cases:
  113. * log1p(x) is NaN with signal if x < -1; log1p(NaN) is NaN with no signal;
  114. * log1p(INF) is +INF; log1p(-1) is -INF with signal;
  115. * only log1p(0)=0 is exact for finite argument.
  116. *
  117. * Accuracy:
  118. * log1p(x) returns the exact log(1+x) nearly rounded. In a test run
  119. * with 1,536,000 random arguments on a VAX, the maximum observed
  120. * error was .846 ulps (units in the last place).
  121. *
  122. * Constants:
  123. * The hexadecimal values are the intended ones for the following constants.
  124. * The decimal values may be used, provided that the compiler will convert
  125. * from decimal to binary accurately enough to produce the hexadecimal values
  126. * shown.
  127. * NOMANUAL
  128. */
  129. double log1p(x)
  130. double x;
  131. {
  132. static double zero=0.0, negone= -1.0, one=1.0,
  133.       half=1.0/2.0, small=1.0E-20;   /* 1+small == 1 */
  134. double logb(),copysign(),scalb(),log__L(),z,s,t,c;
  135. int k,finite();
  136. #if !defined(vax)&&!defined(tahoe)
  137. if(x!=x) return(x); /* x is NaN */
  138. #endif /* !defined(vax)&&!defined(tahoe) */
  139. if(finite(x)) {
  140.    if( x > negone ) {
  141.    /* argument reduction */
  142.       if(copysign(x,one)<small) return(x);
  143.       k=logb(one+x); z=scalb(x,-k); t=scalb(one,-k);
  144.       if(z+t >= sqrt2 )
  145.   { k += 1 ; z *= half; t *= half; }
  146.       t += negone; x = z + t;
  147.       c = (t-x)+z ; /* correction term for x */
  148.      /* compute log(1+x)  */
  149.               s = x/(2+x); t = x*x*half;
  150.       c += (k*ln2lo-c*x);
  151.       z = c+s*(t+log__L(s*s));
  152.       x += (z - t) ;
  153.       return(k*ln2hi+x);
  154.    }
  155. /* end of if (x > negone) */
  156.     else {
  157. #if defined(vax)||defined(tahoe)
  158. extern double infnan();
  159. if ( x == negone )
  160.     return (infnan(-ERANGE)); /* -INF */
  161. else
  162.     return (infnan(EDOM)); /* NaN */
  163. #else /* defined(vax)||defined(tahoe) */
  164. /* x = -1, return -INF with signal */
  165. if ( x == negone ) return( negone/zero );
  166. /* negative argument for log, return NaN with signal */
  167.         else return ( zero / zero );
  168. #endif /* defined(vax)||defined(tahoe) */
  169.     }
  170. }
  171.     /* end of if (finite(x)) */
  172.     /* log(-INF) is NaN */
  173. else if(x<0)
  174.      return(zero/zero);
  175.     /* log(+INF) is INF */
  176. else return(x);
  177. }