ef_sqrt.c
上传用户:caisangzi8
上传日期:2013-10-25
资源大小:15756k
文件大小:2k
源码类别:

DVD

开发平台:

C/C++

  1. /* ef_sqrtf.c -- float version of e_sqrt.c.
  2.  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
  3.  */
  4. /*
  5.  * ====================================================
  6.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  7.  *
  8.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software is freely granted, provided that this notice 
  11.  * is preserved.
  12.  * ====================================================
  13.  */
  14. #include "fdlibm.h"
  15. #ifdef __STDC__
  16. static const float one = 1.0, tiny=1.0e-30;
  17. #else
  18. static float one = 1.0, tiny=1.0e-30;
  19. #endif
  20. #ifdef __STDC__
  21. float __ieee754_sqrtf(float x)
  22. #else
  23. float __ieee754_sqrtf(x)
  24. float x;
  25. #endif
  26. {
  27. float z;
  28. __int32_t  sign = (__int32_t)0x80000000; 
  29. __uint32_t r;
  30. __int32_t ix,s,q,m,t,i;
  31. GET_FLOAT_WORD(ix,x);
  32.     /* take care of Inf and NaN */
  33. if((ix&0x7f800000L)==0x7f800000L) {
  34.     return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
  35.    sqrt(-inf)=sNaN */
  36.     /* take care of zero */
  37. if(ix<=0) {
  38.     if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */
  39.     else if(ix<0)
  40. return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
  41. }
  42.     /* normalize x */
  43. m = (ix>>23);
  44. if(m==0) { /* subnormal x */
  45.     for(i=0;(ix&0x00800000L)==0;i++) ix<<=1;
  46.     m -= i-1;
  47. }
  48. m -= 127; /* unbias exponent */
  49. ix = (ix&0x007fffffL)|0x00800000L;
  50. if(m&1) /* odd m, double x to make it even */
  51.     ix += ix;
  52. m >>= 1; /* m = [m/2] */
  53.     /* generate sqrt(x) bit by bit */
  54. ix += ix;
  55. q = s = 0; /* q = sqrt(x) */
  56. r = 0x01000000L; /* r = moving bit from right to left */
  57. while(r!=0) {
  58.     t = s+r; 
  59.     if(t<=ix) { 
  60. s    = t+r; 
  61. ix  -= t; 
  62. q   += r; 
  63.     } 
  64.     ix += ix;
  65.     r>>=1;
  66. }
  67.     /* use floating add to find out rounding direction */
  68. if(ix!=0) {
  69.     z = one-tiny; /* trigger inexact flag */
  70.     if (z>=one) {
  71.         z = one+tiny;
  72. if (z>one)
  73.     q += 2;
  74. else
  75.     q += (q&1);
  76.     }
  77. }
  78. ix = (q>>1)+0x3f000000L;
  79. ix += (m <<23);
  80. SET_FLOAT_WORD(z,ix);
  81. return z;
  82. }