00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "stdafx.h"
00036
00037 #if defined(__MINGW32__) || (defined(_MSC_VER))
00038
00039 #include "gul_types.h"
00040
00041 using gul::int32;
00042 using gul::uint32;
00043
00044 #define GET_HIGH_WORD(w,x) w = ((int32 *)&(x))[1]
00045 #define GET_LOW_WORD(w,x) w = ((int32 *)&(x))[0]
00046 #define EXTRACT_WORDS(h,l,x) h = ((int32 *)&(x))[1]; l = ((int32 *)&(x))[0];
00047 #define SET_HIGH_WORD(x,w) ((int32 *)&(x))[1] = w;
00048
00049
00050
00051
00052
00053
00054
00055 GULAPI double copysign(double x, double y)
00056 {
00057 uint32 hx,hy;
00058 GET_HIGH_WORD(hx,x);
00059 GET_HIGH_WORD(hy,y);
00060 SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
00061 return x;
00062 }
00063
00064
00065
00066
00067
00068
00069
00070 GULAPI int ilogb(double x)
00071 {
00072 int32 hx,lx,ix;
00073
00074 GET_HIGH_WORD(hx,x);
00075 hx &= 0x7fffffff;
00076 if(hx<0x00100000)
00077 {
00078 GET_LOW_WORD(lx,x);
00079 if((hx|lx)==0)
00080 return 0x80000001;
00081 else
00082 {
00083 if(hx==0)
00084 {
00085 for (ix = -1043; lx>0; lx<<=1) ix -=1;
00086 }
00087 else
00088 {
00089 for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
00090 }
00091 return ix;
00092 }
00093 }
00094 else if (hx<0x7ff00000)
00095 return (hx>>20)-1023;
00096
00097 return 0x7fffffff;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107 static const double
00108 two54 = 1.80143985094819840000e+16,
00109 twom54 = 5.55111512312578270212e-17,
00110 hug = 1.0e+300,
00111 tiny = 1.0e-300;
00112
00113 GULAPI double scalbn (double x, int n)
00114 {
00115 int32 k,hx,lx;
00116 EXTRACT_WORDS(hx,lx,x);
00117 k = (hx&0x7ff00000)>>20;
00118 if (k==0)
00119 {
00120 if ((lx|(hx&0x7fffffff))==0) return x;
00121 x *= two54;
00122 GET_HIGH_WORD(hx,x);
00123 k = ((hx&0x7ff00000)>>20) - 54;
00124 if (n< -50000) return tiny*x;
00125 }
00126 if (k==0x7ff) return x+x;
00127 k = k+n;
00128 if (k > 0x7fe) return hug*copysign(hug,x);
00129 if (k > 0)
00130 {
00131 SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
00132 return x;
00133 }
00134 if (k <= -54)
00135 if (n > 50000)
00136 return hug*copysign(hug,x);
00137 else
00138 return tiny*copysign(tiny,x);
00139 k += 54;
00140 SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
00141 return x*twom54;
00142 }
00143
00144 #endif
00145