00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #if defined(LIBM_SCCS) && !defined(lint)
00014 static char rcsid[] = "$NetBSD: e_fmod.c,v 1.8 1995/05/10 20:45:07 jtc Exp $";
00015 #endif
00016
00017
00018
00019
00020
00021
00022
00023 #include "math.h"
00024 #include "mathP.h"
00025
00026 #ifdef __STDC__
00027 static const double one = 1.0, Zero[] = {0.0, -0.0,};
00028 #else
00029 static double one = 1.0, Zero[] = {0.0, -0.0,};
00030 #endif
00031
00032 #ifdef __STDC__
00033 double __ieee754_fmod(double x, double y)
00034 #else
00035 double __ieee754_fmod(x,y)
00036 double x,y ;
00037 #endif
00038 {
00039 int32_t n,hx,hy,hz,ix,iy,sx,i;
00040 u_int32_t lx,ly,lz;
00041
00042 EXTRACT_WORDS(hx,lx,x);
00043 EXTRACT_WORDS(hy,ly,y);
00044 sx = hx&0x80000000;
00045 hx ^=sx;
00046 hy &= 0x7fffffff;
00047
00048
00049 if((hy|ly)==0||(hx>=0x7ff00000)||
00050 ((hy|((ly|-ly)>>31))>0x7ff00000))
00051 return (x*y)/(x*y);
00052 if(hx<=hy) {
00053 if((hx<hy)||(lx<ly)) return x;
00054 if(lx==ly)
00055 return Zero[(u_int32_t)sx>>31];
00056 }
00057
00058
00059 if(hx<0x00100000) {
00060 if(hx==0) {
00061 for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
00062 } else {
00063 for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
00064 }
00065 } else ix = (hx>>20)-1023;
00066
00067
00068 if(hy<0x00100000) {
00069 if(hy==0) {
00070 for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
00071 } else {
00072 for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
00073 }
00074 } else iy = (hy>>20)-1023;
00075
00076
00077 if(ix >= -1022)
00078 hx = 0x00100000|(0x000fffff&hx);
00079 else {
00080 n = -1022-ix;
00081 if(n<=31) {
00082 hx = (hx<<n)|(lx>>(32-n));
00083 lx <<= n;
00084 } else {
00085 hx = lx<<(n-32);
00086 lx = 0;
00087 }
00088 }
00089 if(iy >= -1022)
00090 hy = 0x00100000|(0x000fffff&hy);
00091 else {
00092 n = -1022-iy;
00093 if(n<=31) {
00094 hy = (hy<<n)|(ly>>(32-n));
00095 ly <<= n;
00096 } else {
00097 hy = ly<<(n-32);
00098 ly = 0;
00099 }
00100 }
00101
00102
00103 n = ix - iy;
00104 while(n--) {
00105 hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
00106 if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
00107 else {
00108 if((hz|lz)==0)
00109 return Zero[(u_int32_t)sx>>31];
00110 hx = hz+hz+(lz>>31); lx = lz+lz;
00111 }
00112 }
00113 hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
00114 if(hz>=0) {hx=hz;lx=lz;}
00115
00116
00117 if((hx|lx)==0)
00118 return Zero[(u_int32_t)sx>>31];
00119 while(hx<0x00100000) {
00120 hx = hx+hx+(lx>>31); lx = lx+lx;
00121 iy -= 1;
00122 }
00123 if(iy>= -1022) {
00124 hx = ((hx-0x00100000)|((iy+1023)<<20));
00125 INSERT_WORDS(x,hx|sx,lx);
00126 } else {
00127 n = -1022 - iy;
00128 if(n<=20) {
00129 lx = (lx>>n)|((u_int32_t)hx<<(32-n));
00130 hx >>= n;
00131 } else if (n<=31) {
00132 lx = (hx<<(32-n))|(lx>>n); hx = sx;
00133 } else {
00134 lx = hx>>(n-32); hx = sx;
00135 }
00136 INSERT_WORDS(x,hx|sx,lx);
00137 x *= one;
00138 }
00139 return x;
00140 }