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

VxWorks

开发平台:

C/C++

  1. /* @(#)e_fmod.c 5.1 93/09/24 */
  2. /*
  3.  * ====================================================
  4.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  5.  *
  6.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software is freely granted, provided that this notice 
  9.  * is preserved.
  10.  * ====================================================
  11.  */
  12. /* 
  13.  * __ieee754_fmod(x,y)
  14.  * Return x mod y in exact arithmetic
  15.  * Method: shift and subtract
  16.  */
  17. #include "fdlibm.h"
  18. #ifndef _DOUBLE_IS_32BITS
  19. #ifdef __STDC__
  20. static const double one = 1.0, Zero[] = {0.0, -0.0,};
  21. #else
  22. static double one = 1.0, Zero[] = {0.0, -0.0,};
  23. #endif
  24. #ifdef __STDC__
  25. double __ieee754_fmod(double x, double y)
  26. #else
  27. double __ieee754_fmod(x,y)
  28. double x,y ;
  29. #endif
  30. {
  31. __int32_t n,hx,hy,hz,ix,iy,sx,i;
  32. __uint32_t lx,ly,lz;
  33. EXTRACT_WORDS(hx,lx,x);
  34. EXTRACT_WORDS(hy,ly,y);
  35. sx = hx&0x80000000; /* sign of x */
  36. hx ^=sx; /* |x| */
  37. hy &= 0x7fffffff; /* |y| */
  38.     /* purge off exception values */
  39. if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
  40.   ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */
  41.     return (x*y)/(x*y);
  42. if(hx<=hy) {
  43.     if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
  44.     if(lx==ly) 
  45. return Zero[(__uint32_t)sx>>31]; /* |x|=|y| return x*0*/
  46. }
  47.     /* determine ix = ilogb(x) */
  48. if(hx<0x00100000) { /* subnormal x */
  49.     if(hx==0) {
  50. for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
  51.     } else {
  52. for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
  53.     }
  54. } else ix = (hx>>20)-1023;
  55.     /* determine iy = ilogb(y) */
  56. if(hy<0x00100000) { /* subnormal y */
  57.     if(hy==0) {
  58. for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
  59.     } else {
  60. for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
  61.     }
  62. } else iy = (hy>>20)-1023;
  63.     /* set up {hx,lx}, {hy,ly} and align y to x */
  64. if(ix >= -1022) 
  65.     hx = 0x00100000|(0x000fffff&hx);
  66. else { /* subnormal x, shift x to normal */
  67.     n = -1022-ix;
  68.     if(n<=31) {
  69.         hx = (hx<<n)|(lx>>(32-n));
  70.         lx <<= n;
  71.     } else {
  72. hx = lx<<(n-32);
  73. lx = 0;
  74.     }
  75. }
  76. if(iy >= -1022) 
  77.     hy = 0x00100000|(0x000fffff&hy);
  78. else { /* subnormal y, shift y to normal */
  79.     n = -1022-iy;
  80.     if(n<=31) {
  81.         hy = (hy<<n)|(ly>>(32-n));
  82.         ly <<= n;
  83.     } else {
  84. hy = ly<<(n-32);
  85. ly = 0;
  86.     }
  87. }
  88.     /* fix point fmod */
  89. n = ix - iy;
  90. while(n--) {
  91.     hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
  92.     if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
  93.     else {
  94.      if((hz|lz)==0)  /* return sign(x)*0 */
  95.     return Zero[(__uint32_t)sx>>31];
  96.      hx = hz+hz+(lz>>31); lx = lz+lz;
  97.     }
  98. }
  99. hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
  100. if(hz>=0) {hx=hz;lx=lz;}
  101.     /* convert back to floating value and restore the sign */
  102. if((hx|lx)==0)  /* return sign(x)*0 */
  103.     return Zero[(__uint32_t)sx>>31];
  104. while(hx<0x00100000) { /* normalize x */
  105.     hx = hx+hx+(lx>>31); lx = lx+lx;
  106.     iy -= 1;
  107. }
  108. if(iy>= -1022) { /* normalize output */
  109.     hx = ((hx-0x00100000)|((iy+1023)<<20));
  110.     INSERT_WORDS(x,hx|sx,lx);
  111. } else { /* subnormal output */
  112.     n = -1022 - iy;
  113.     if(n<=20) {
  114. lx = (lx>>n)|((__uint32_t)hx<<(32-n));
  115. hx >>= n;
  116.     } else if (n<=31) {
  117. lx = (hx<<(32-n))|(lx>>n); hx = sx;
  118.     } else {
  119. lx = hx>>(n-32); hx = sx;
  120.     }
  121.     INSERT_WORDS(x,hx|sx,lx);
  122.     x *= one; /* create necessary signal */
  123. }
  124. return x; /* exact output */
  125. }
  126. #endif /* defined(_DOUBLE_IS_32BITS) */