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

VxWorks

开发平台:

C/C++

  1. /* sqrt.c - software version of sqare-root routine */
  2. /* Copyright 1992-1994 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01h,18nov99,dra  added SPARCV9 support for h/w sqrt.
  7. 01g,05feb99,dgp  document errno values
  8. 01f,02sep93,jwt  moved sparcHardSqrt to src/arch/sparc/sparcLib.c.
  9. 01e,05feb93,jdi  doc changes based on kdl review.
  10. 01d,02dec92,jdi  doc tweaks.
  11. 01c,28oct92,jdi  documentation cleanup.
  12. 01b,13oct92,jdi  mangen fixes.
  13. 01a,23jun92,kdl  extracted from v.01d of support.c.
  14. */
  15. /*
  16. DESCRIPTION
  17. * Copyright (c) 1985 Regents of the University of California.
  18. * All rights reserved.
  19. *
  20. * Redistribution and use in source and binary forms are permitted
  21. * provided that the above copyright notice and this paragraph are
  22. * duplicated in all such forms and that any documentation,
  23. * advertising materials, and other materials related to such
  24. * distribution and use acknowledge that the software was developed
  25. * by the University of California, Berkeley.  The name of the
  26. * University may not be used to endorse or promote products derived
  27. * from this software without specific prior written permission.
  28. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  29. * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  30. * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  31. *
  32. * All recipients should regard themselves as participants in an ongoing
  33. * research project and hence should feel obligated to report their
  34. * experiences (good or bad) with these elementary function codes, using
  35. * the sendbug(8) program, to the authors.
  36. *
  37. * Some IEEE standard 754 recommended functions and remainder and sqrt for
  38. * supporting the C elementary functions.
  39. * -------------------------------------------------------------------------
  40. * WARNING:
  41. *      These codes are developed (in double) to support the C elementary
  42. * functions temporarily. They are not universal, and some of them are very
  43. * slow (in particular, drem and sqrt is extremely inefficient). Each
  44. * computer system should have its implementation of these functions using
  45. * its own assembler.
  46. * -------------------------------------------------------------------------
  47. *
  48. * IEEE 754 required operations:
  49. *     drem(x,p)
  50. *              returns  x REM y  =  x - [x/y]*y , where [x/y] is the integer
  51. *              nearest x/y; in half way case, choose the even one.
  52. *     sqrt(x)
  53. *              returns the square root of x correctly rounded according to
  54. * the rounding mod.
  55. *
  56. * IEEE 754 recommended functions:
  57. * (a) copysign(x,y)
  58. *              returns x with the sign of y.
  59. * (b) scalb(x,N)
  60. *              returns  x * (2**N), for integer values N.
  61. * (c) logb(x)
  62. *              returns the unbiased exponent of x, a signed integer in
  63. *              double precision, except that logb(0) is -INF, logb(INF)
  64. *              is +INF, and logb(NAN) is that NAN.
  65. * (d) finite(x)
  66. *              returns the value TRUE if -INF < x < +INF and returns
  67. *              FALSE otherwise.
  68. *
  69. *
  70. * CODED IN C BY K.C. NG, 11/25/84;
  71. * REVISED BY K.C. NG on 1/22/85, 2/13/85, 3/24/85.
  72. *
  73. * SEE ALSO: American National Standard X3.159-1989
  74. * NOMANUAL
  75. */
  76. #include "vxWorks.h"
  77. #include "math.h"
  78. #include "private/mathP.h"
  79. #include "errno.h"
  80. extern double scalb();
  81. extern double logb();
  82. extern int finite();
  83. /*******************************************************************************
  84. *
  85. * sqrt - compute a non-negative square root (ANSI)
  86. *
  87. * This routine computes the non-negative square root of <x> in double
  88. * precision.  A domain error occurs if the argument is negative.
  89. *
  90. * INCLUDE FILES: math.h
  91. *
  92. * RETURNS: The double-precision square root of <x>.
  93. *
  94. * ERROR: EDOM
  95. *
  96. * SEE ALSO: mathALib
  97. */
  98. double sqrt
  99.     (
  100.     double x /* value to compute the square root of */
  101.     )
  102.     {
  103.         double q,s,b,r;
  104.         double t,zero=0.0;
  105.         int m,n,i;
  106. #if defined(vax)||defined(tahoe)
  107.         int k=54;
  108. #else /* defined(vax)||defined(tahoe) */
  109.         int k=51;
  110. #endif /* defined(vax)||defined(tahoe) */
  111. /* Select hardware/software square root */
  112. #if (CPU_FAMILY == SPARC) || (CPU_FAMILY == SPARCV9)
  113.         extern BOOL sparcHardSqrt;
  114.         if (sparcHardSqrt == TRUE)
  115.     {
  116.     double  sqrtHw();
  117.     return (sqrtHw (x));
  118.     }
  119. #endif /* (CPU_FAMILY == SPARC) */
  120.     /* sqrt(NaN) is NaN, sqrt(+-0) = +-0 */
  121.         if(x!=x||x==zero) return(x);
  122.     /* sqrt(negative) is invalid */
  123.         if(x<zero) {
  124. #if defined(vax)||defined(tahoe)
  125. extern double infnan();
  126. return (infnan(EDOM)); /* NaN */
  127. #else /* defined(vax)||defined(tahoe) */
  128. errno = EDOM; 
  129. return(zero/zero);
  130. #endif /* defined(vax)||defined(tahoe) */
  131. }
  132.     /* sqrt(INF) is INF */
  133.         if(!finite(x)) return(x);
  134.     /* scale x to [1,4) */
  135.         n=logb(x);
  136.         x=scalb(x,-n);
  137.         if((m=logb(x))!=0) x=scalb(x,-m);       /* subnormal number */
  138.         m += n;
  139.         n = m/2;
  140.         if((n+n)!=m) {x *= 2; m -=1; n=m/2;}
  141.     /* generate sqrt(x) bit by bit (accumulating in q) */
  142.             q=1.0; s=4.0; x -= 1.0; r=1;
  143.             for(i=1;i<=k;i++) {
  144.                 t=s+1; x *= 4; r /= 2;
  145.                 if(t<=x) {
  146.                     s=t+t+2, x -= t; q += r;}
  147.                 else
  148.                     s *= 2;
  149.                 }
  150.     /* generate the last bit and determine the final rounding */
  151.             r/=2; x *= 4;
  152.             if(x==zero) goto end; 100+r; /* trigger inexact flag */
  153.             if(s<x) {
  154.                 q+=r; x -=s; s += 2; s *= 2; x *= 4;
  155.                 t = (x-s)-5;
  156.                 b=1.0+3*r/4; if(b==1.0) goto end; /* b==1 : Round-to-zero */
  157.                 b=1.0+r/4;   if(b>1.0) t=1; /* b>1 : Round-to-(+INF) */
  158.                 if(t>=0) q+=r; }       /* else: Round-to-nearest */
  159.             else {
  160.                 s *= 2; x *= 4;
  161.                 t = (x-s)-1;
  162.                 b=1.0+3*r/4; if(b==1.0) goto end;
  163.                 b=1.0+r/4;   if(b>1.0) t=1;
  164.                 if(t>=0) q+=r; }
  165. end:        return(scalb(q,n));
  166.     }