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

VxWorks

开发平台:

C/C++

  1. /* cabs.c - math routines */
  2. /* Copyright 1992 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01d,15feb93,jdi  made hypot() NOMANUAL.
  7. 01c,14oct92,jdi  made cabs() NOMANUAL.
  8. 01b,13oct92,jdi  mangen fixes.
  9. 01a,30jul92,smb  documentation.
  10. */
  11. /*
  12. DESCRIPTION
  13. * Copyright (c) 1985 Regents of the University of California.
  14. * All rights reserved.
  15. *
  16. * Redistribution and use in source and binary forms are permitted
  17. * provided that the above copyright notice and this paragraph are
  18. * duplicated in all such forms and that any documentation,
  19. * advertising materials, and other materials related to such
  20. * distribution and use acknowledge that the software was developed
  21. * by the University of California, Berkeley.  The name of the
  22. * University may not be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  25. * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  26. * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  27. *
  28. * All recipients should regard themselves as participants in an ongoing
  29. * research project and hence should feel obligated to report their
  30. * experiences (good or bad) with these elementary function codes, using
  31. * the sendbug(8) program, to the authors.
  32. *
  33. #ifndef lint
  34. static char sccsid[] = "@(#)cabs.c 5.3 (Berkeley) 6/30/88";
  35. #endif * not lint *
  36. SEE ALSO: American National Standard X3.159-1989
  37. NOMANUAL
  38. */
  39. #include "vxWorks.h"
  40. #include "math.h"
  41. #if defined(vax)||defined(tahoe) /* VAX D format */
  42. #ifdef vax
  43. #define _0x(A,B) 0x/**/A/**/B
  44. #else /* vax */
  45. #define _0x(A,B) 0x/**/B/**/A
  46. #endif /* vax */
  47. /* static double */
  48. /* r2p1hi =  2.4142135623730950345E0     , Hex  2^  2   *  .9A827999FCEF32 */
  49. /* r2p1lo =  1.4349369327986523769E-17   , Hex  2^-55   *  .84597D89B3754B */
  50. /* sqrt2  =  1.4142135623730950622E0     ; Hex  2^  1   *  .B504F333F9DE65 */
  51. static long    r2p1hix[] = { _0x(8279,411a), _0x(ef32,99fc)};
  52. static long    r2p1lox[] = { _0x(597d,2484), _0x(754b,89b3)};
  53. static long     sqrt2x[] = { _0x(04f3,40b5), _0x(de65,33f9)};
  54. #define   r2p1hi    (*(double*)r2p1hix)
  55. #define   r2p1lo    (*(double*)r2p1lox)
  56. #define    sqrt2    (*(double*)sqrt2x)
  57. #else /* defined(vax)||defined(tahoe) */
  58. static double
  59. r2p1hi =  2.4142135623730949234E0     , /*Hex  2^1     *  1.3504F333F9DE6 */
  60. r2p1lo =  1.2537167179050217666E-16   , /*Hex  2^-53   *  1.21165F626CDD5 */
  61. sqrt2  =  1.4142135623730951455E0     ; /*Hex  2^  0   *  1.6A09E667F3BCD */
  62. #endif /* defined(vax)||defined(tahoe) */
  63. /******************************************************************************
  64. *
  65. * hypot - return the square root of X^2 + Y^2 where Z = X + iY
  66. *
  67. * This routine returns the square root of X^2 + Y^2 where Z=X+iY
  68. * in double precision (VAX D format 56 bits, IEEE double 53 bits).
  69. *
  70. * Required system support functions: copysign(), finite(), scalb(), sqrt().
  71. *
  72. * Method:
  73. * 1. replace x by |x| and y by |y|, and swap x and
  74. *    y if y > x (hence x is never smaller than y).
  75. * 2. Hypot(x,y) is computed by:
  76. * .CS
  77. *   Case I, x/y > 2
  78. *
  79. *        y
  80. * hypot = x + -----------------------------
  81. *     2
  82. *     sqrt ( 1 + [x/y]  )  +  x/y
  83. *
  84. *   Case II, x/y <= 2
  85. *    y
  86. * hypot = x + --------------------------------------------------
  87. *      2
  88. * [x/y]   -  2
  89. *    (sqrt(2)+1) + (x-y)/y + -----------------------------
  90. *   2
  91. *   sqrt ( 1 + [x/y]  )  + sqrt(2)
  92. * .CE
  93. *
  94. * Special cases:
  95. * .CS
  96. * hypot(x,y) is INF if x or y is +INF or -INF; else
  97. * hypot(x,y) is NAN if x or y is NAN.
  98. * .CE
  99. *
  100. * ACCURACY:
  101. * hypot() returns the sqrt(x^2+y^2) with error less than 1 ulps (units
  102. * in the last place).  See Kahan's "Interval Arithmetic Options in the
  103. * Proposed IEEE Floating Point Arithmetic Standard", Interval Mathematics
  104. * 1980, Edited by Karl L.E. Nickel, pp 99-128.  (A faster but less accurate
  105. * code follows in comments.)  In a test run with 500,000 random arguments
  106. * on a VAX, the maximum observed error was 0.959 ulps.
  107. *
  108. * CONSTANTS:
  109. * The hexadecimal values are the intended ones for the following constants.
  110. * The decimal values may be used, provided that the compiler will convert
  111. * from decimal to binary accurately enough to produce the hexadecimal values
  112. * shown.
  113. *
  114. * RETURNS: The square root of X^2 + Y^2 where Z = X + iY.
  115. *
  116. * INTERNAL:
  117. * Coded in C by K.C. Ng, 11/28/84;
  118. * Revised by K.C. Ng, 7/12/85.
  119. */
  120. double hypot(x,y)
  121.     double x, y;
  122. {
  123. static double zero=0, one=1,
  124.       small=1.0E-18; /* fl(1+small)==1 */
  125. static ibig=30; /* fl(1+2**(2*ibig))==1 */
  126. double copysign(),scalb(),logb(),sqrt(),t,r;
  127. int finite(), exp;
  128. if(finite(x))
  129.     if(finite(y))
  130.     {
  131. x=copysign(x,one);
  132. y=copysign(y,one);
  133. if(y > x)
  134.     { t=x; x=y; y=t; }
  135. if(x == zero) return(zero);
  136. if(y == zero) return(x);
  137. exp= logb(x);
  138. if(exp-(int)logb(y) > ibig )
  139. /* raise inexact flag and return |x| */
  140.    { one+small; return(x); }
  141.     /* start computing sqrt(x^2 + y^2) */
  142. r=x-y;
  143. if(r>y) {  /* x/y > 2 */
  144.     r=x/y;
  145.     r=r+sqrt(one+r*r); }
  146. else { /* 1 <= x/y <= 2 */
  147.     r/=y; t=r*(r+2.0);
  148.     r+=t/(sqrt2+sqrt(2.0+t));
  149.     r+=r2p1lo; r+=r2p1hi; }
  150. r=y/r;
  151. return(x+r);
  152.     }
  153.     else if(y==y)       /* y is +-INF */
  154.      return(copysign(y,one));
  155.     else
  156.      return(y);    /* y is NaN and x is finite */
  157. else if(x==x)     /* x is +-INF */
  158.          return (copysign(x,one));
  159. else if(finite(y))
  160.          return(x);    /* x is NaN, y is finite */
  161. #if !defined(vax)&&!defined(tahoe)
  162. else if(y!=y) return(y);  /* x and y is NaN */
  163. #endif /* !defined(vax)&&!defined(tahoe) */
  164. else return(copysign(y,one));   /* y is INF */
  165. }
  166. /*****************************************************************************
  167. *
  168. * cabs - return the absolute value of the complex number Z = X + iY
  169. *
  170. * This routine returns the absolute value of the complex number Z = X + iY,
  171. * in double precision (VAX D format 56 bits, IEEE double 53 bits).
  172. *
  173. * Required kernel function:  hypot()
  174. *
  175. * Method :
  176. * .CS
  177. * cabs(z) = hypot(x,y) .
  178. * .CE
  179. *
  180. * RETURNS: The absolute value of Z = X + iY.
  181. *
  182. * INTERNAL:
  183. * Coded in C by K.C. Ng, 11/28/84.
  184. * Revised by K.C. Ng, 7/12/85.
  185. *
  186. * NOMANUAL
  187. */
  188. double cabs(z)
  189.     struct { double x, y;} z;
  190. {
  191. return hypot(z.x,z.y);
  192. }
  193. double
  194. z_abs(z)
  195. struct { double x,y;} *z;
  196. {
  197. return hypot(z->x,z->y);
  198. }