make type punning of floating point/int in float_math and double_math use union to avoid warnings (#600)
This commit is contained in:
		@ -41,11 +41,25 @@ typedef int64_t i64;
 | 
				
			|||||||
#define DUNPACK(x,e,m) e=((x)>>52)&0x7ff,m=((x)&0x000fffffffffffffULL)|0x0010000000000000ULL
 | 
					#define DUNPACK(x,e,m) e=((x)>>52)&0x7ff,m=((x)&0x000fffffffffffffULL)|0x0010000000000000ULL
 | 
				
			||||||
#define DUNPACKS(x,s,e,m) s=((x)>>63),DUNPACK((x),(e),(m))
 | 
					#define DUNPACKS(x,s,e,m) s=((x)>>63),DUNPACK((x),(e),(m))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_Pragma("GCC diagnostic push")
 | 
					typedef union {
 | 
				
			||||||
_Pragma("GCC diagnostic ignored \"-Wstrict-aliasing\"")
 | 
					    double d;
 | 
				
			||||||
 | 
					    ui64 ix;
 | 
				
			||||||
 | 
					} double_ui64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline double ui642double(ui64 ix) {
 | 
				
			||||||
 | 
					    double_ui64 tmp;
 | 
				
			||||||
 | 
					    tmp.ix = ix;
 | 
				
			||||||
 | 
					    return tmp.d;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline ui64 double2ui64(double d) {
 | 
				
			||||||
 | 
					    double_ui64 tmp;
 | 
				
			||||||
 | 
					    tmp.d = d;
 | 
				
			||||||
 | 
					    return tmp.ix;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline bool disnan(double x) {
 | 
					static inline bool disnan(double x) {
 | 
				
			||||||
    ui64 ix=*(ui64*)&x;
 | 
					    ui64 ix= double2ui64(x);
 | 
				
			||||||
    // checks the top bit of the low 32 bit of the NAN, but it I think that is ok
 | 
					    // checks the top bit of the low 32 bit of the NAN, but it I think that is ok
 | 
				
			||||||
    return ((uint32_t)(ix >> 31)) > 0xffe00000u;
 | 
					    return ((uint32_t)(ix >> 31)) > 0xffe00000u;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -59,17 +73,17 @@ static inline bool disnan(double x) {
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int dgetsignexp(double x) {
 | 
					static inline int dgetsignexp(double x) {
 | 
				
			||||||
    ui64 ix=*(ui64*)&x;
 | 
					    ui64 ix=double2ui64(x);
 | 
				
			||||||
    return (ix>>52)&0xfff;
 | 
					    return (ix>>52)&0xfff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int dgetexp(double x) {
 | 
					static inline int dgetexp(double x) {
 | 
				
			||||||
    ui64 ix=*(ui64*)&x;
 | 
					    ui64 ix=double2ui64(x);
 | 
				
			||||||
    return (ix>>52)&0x7ff;
 | 
					    return (ix>>52)&0x7ff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline double dldexp(double x,int de) {
 | 
					static inline double dldexp(double x,int de) {
 | 
				
			||||||
    ui64 ix=*(ui64*)&x,iy;
 | 
					    ui64 ix=double2ui64(x),iy;
 | 
				
			||||||
    int e;
 | 
					    int e;
 | 
				
			||||||
    e=dgetexp(x);
 | 
					    e=dgetexp(x);
 | 
				
			||||||
    if(e==0||e==0x7ff) return x;
 | 
					    if(e==0||e==0x7ff) return x;
 | 
				
			||||||
@ -77,7 +91,7 @@ static inline double dldexp(double x,int de) {
 | 
				
			|||||||
    if(e<=0) iy=ix&0x8000000000000000ULL; // signed zero for underflow
 | 
					    if(e<=0) iy=ix&0x8000000000000000ULL; // signed zero for underflow
 | 
				
			||||||
    else if(e>=0x7ff) iy=(ix&0x8000000000000000ULL)|0x7ff0000000000000ULL; // signed infinity on overflow
 | 
					    else if(e>=0x7ff) iy=(ix&0x8000000000000000ULL)|0x7ff0000000000000ULL; // signed infinity on overflow
 | 
				
			||||||
    else iy=ix+((ui64)de<<52);
 | 
					    else iy=ix+((ui64)de<<52);
 | 
				
			||||||
    return *(double*)&iy;
 | 
					    return ui642double(iy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
double WRAPPER_FUNC(ldexp)(double x, int de) {
 | 
					double WRAPPER_FUNC(ldexp)(double x, int de) {
 | 
				
			||||||
@ -87,9 +101,9 @@ double WRAPPER_FUNC(ldexp)(double x, int de) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline double dcopysign(double x,double y) {
 | 
					static inline double dcopysign(double x,double y) {
 | 
				
			||||||
    ui64 ix=*(ui64*)&x,iy=*(ui64*)&y;
 | 
					    ui64 ix=double2ui64(x),iy=double2ui64(y);
 | 
				
			||||||
    ix=((ix&0x7fffffffffffffffULL)|(iy&0x8000000000000000ULL));
 | 
					    ix=((ix&0x7fffffffffffffffULL)|(iy&0x8000000000000000ULL));
 | 
				
			||||||
    return *(double*)&ix;
 | 
					    return ui642double(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
double WRAPPER_FUNC(copysign)(double x, double y) {
 | 
					double WRAPPER_FUNC(copysign)(double x, double y) {
 | 
				
			||||||
@ -104,7 +118,7 @@ static inline int dispinf(double x)  { return dgetsignexp(x)==0x7ff; }
 | 
				
			|||||||
static inline int disminf(double x)  { return dgetsignexp(x)==0xfff; }
 | 
					static inline int disminf(double x)  { return dgetsignexp(x)==0xfff; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int disint(double x) {
 | 
					static inline int disint(double x) {
 | 
				
			||||||
    ui64 ix=*(ui64*)&x,m;
 | 
					    ui64 ix=double2ui64(x),m;
 | 
				
			||||||
    int e=dgetexp(x);
 | 
					    int e=dgetexp(x);
 | 
				
			||||||
    if(e==0) return 1;       // 0 is an integer
 | 
					    if(e==0) return 1;       // 0 is an integer
 | 
				
			||||||
    e-=0x3ff;                // remove exponent bias
 | 
					    e-=0x3ff;                // remove exponent bias
 | 
				
			||||||
@ -117,7 +131,7 @@ static inline int disint(double x) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int disoddint(double x) {
 | 
					static inline int disoddint(double x) {
 | 
				
			||||||
    ui64 ix=*(ui64*)&x,m;
 | 
					    ui64 ix=double2ui64(x),m;
 | 
				
			||||||
    int e=dgetexp(x);
 | 
					    int e=dgetexp(x);
 | 
				
			||||||
    e-=0x3ff;                // remove exponent bias
 | 
					    e-=0x3ff;                // remove exponent bias
 | 
				
			||||||
    if(e<0) return 0;        // |x|<1; 0 is not odd
 | 
					    if(e<0) return 0;        // |x|<1; 0 is not odd
 | 
				
			||||||
@ -130,24 +144,24 @@ static inline int disoddint(double x) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int disstrictneg(double x) {
 | 
					static inline int disstrictneg(double x) {
 | 
				
			||||||
    ui64 ix=*(ui64*)&x;
 | 
					    ui64 ix=double2ui64(x);
 | 
				
			||||||
    if(diszero(x)) return 0;
 | 
					    if(diszero(x)) return 0;
 | 
				
			||||||
    return ix>>63;
 | 
					    return ix>>63;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int disneg(double x) {
 | 
					static inline int disneg(double x) {
 | 
				
			||||||
    ui64 ix=*(ui64*)&x;
 | 
					    ui64 ix=double2ui64(x);
 | 
				
			||||||
    return ix>>63;
 | 
					    return ix>>63;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline double dneg(double x) {
 | 
					static inline double dneg(double x) {
 | 
				
			||||||
    ui64 ix=*(ui64*)&x;
 | 
					    ui64 ix=double2ui64(x);
 | 
				
			||||||
    ix^=0x8000000000000000ULL;
 | 
					    ix^=0x8000000000000000ULL;
 | 
				
			||||||
    return *(double*)&ix;
 | 
					    return ui642double(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int dispo2(double x) {
 | 
					static inline int dispo2(double x) {
 | 
				
			||||||
    ui64 ix=*(ui64*)&x;
 | 
					    ui64 ix=double2ui64(x);
 | 
				
			||||||
    if(diszero(x)) return 0;
 | 
					    if(diszero(x)) return 0;
 | 
				
			||||||
    if(disinf(x)) return 0;
 | 
					    if(disinf(x)) return 0;
 | 
				
			||||||
    ix&=0x000fffffffffffffULL;
 | 
					    ix&=0x000fffffffffffffULL;
 | 
				
			||||||
@ -164,33 +178,33 @@ static inline double dnan_or(double x) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
double WRAPPER_FUNC(trunc)(double x) {
 | 
					double WRAPPER_FUNC(trunc)(double x) {
 | 
				
			||||||
    check_nan_d1(x);
 | 
					    check_nan_d1(x);
 | 
				
			||||||
    ui64 ix=*(ui64*)&x,m;
 | 
					    ui64 ix=double2ui64(x),m;
 | 
				
			||||||
    int e=dgetexp(x);
 | 
					    int e=dgetexp(x);
 | 
				
			||||||
    e-=0x3ff;                // remove exponent bias
 | 
					    e-=0x3ff;                // remove exponent bias
 | 
				
			||||||
    if(e<0) {                // |x|<1
 | 
					    if(e<0) {                // |x|<1
 | 
				
			||||||
        ix&=0x8000000000000000ULL;
 | 
					        ix&=0x8000000000000000ULL;
 | 
				
			||||||
        return *(double*)&ix;
 | 
					        return ui642double(ix);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    e=52-e;                  // bit position in mantissa with significance 1
 | 
					    e=52-e;                  // bit position in mantissa with significance 1
 | 
				
			||||||
    if(e<=0) return x;       // |x| large, so must be an integer
 | 
					    if(e<=0) return x;       // |x| large, so must be an integer
 | 
				
			||||||
    m=(1ULL<<e)-1;           // mask for bits of significance <1
 | 
					    m=(1ULL<<e)-1;           // mask for bits of significance <1
 | 
				
			||||||
    ix&=~m;
 | 
					    ix&=~m;
 | 
				
			||||||
    return *(double*)&ix;
 | 
					    return ui642double(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
double WRAPPER_FUNC(round)(double x) {
 | 
					double WRAPPER_FUNC(round)(double x) {
 | 
				
			||||||
    check_nan_d1(x);
 | 
					    check_nan_d1(x);
 | 
				
			||||||
    ui64 ix=*(ui64*)&x,m;
 | 
					    ui64 ix=double2ui64(x),m;
 | 
				
			||||||
    int e=dgetexp(x);
 | 
					    int e=dgetexp(x);
 | 
				
			||||||
    e-=0x3ff;                // remove exponent bias
 | 
					    e-=0x3ff;                // remove exponent bias
 | 
				
			||||||
    if(e<-1) {               // |x|<0.5
 | 
					    if(e<-1) {               // |x|<0.5
 | 
				
			||||||
        ix&=0x8000000000000000ULL;
 | 
					        ix&=0x8000000000000000ULL;
 | 
				
			||||||
        return *(double*)&ix;
 | 
					        return ui642double(ix);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(e==-1) {              // 0.5<=|x|<1
 | 
					    if(e==-1) {              // 0.5<=|x|<1
 | 
				
			||||||
        ix&=0x8000000000000000ULL;
 | 
					        ix&=0x8000000000000000ULL;
 | 
				
			||||||
        ix|=0x3ff0000000000000ULL;        // ±1
 | 
					        ix|=0x3ff0000000000000ULL;        // ±1
 | 
				
			||||||
        return *(double*)&ix;
 | 
					        return ui642double(ix);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    e=52-e;                  // bit position in mantissa with significance 1, <=52
 | 
					    e=52-e;                  // bit position in mantissa with significance 1, <=52
 | 
				
			||||||
    if(e<=0) return x;       // |x| large, so must be an integer
 | 
					    if(e<=0) return x;       // |x| large, so must be an integer
 | 
				
			||||||
@ -198,16 +212,16 @@ double WRAPPER_FUNC(round)(double x) {
 | 
				
			|||||||
    ix+=m;
 | 
					    ix+=m;
 | 
				
			||||||
    m=m+m-1;                 // mask for bits of significance <1
 | 
					    m=m+m-1;                 // mask for bits of significance <1
 | 
				
			||||||
    ix&=~m;
 | 
					    ix&=~m;
 | 
				
			||||||
    return *(double*)&ix;
 | 
					    return ui642double(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
double WRAPPER_FUNC(floor)(double x) {
 | 
					double WRAPPER_FUNC(floor)(double x) {
 | 
				
			||||||
    check_nan_d1(x);
 | 
					    check_nan_d1(x);
 | 
				
			||||||
    ui64 ix=*(ui64*)&x,m;
 | 
					    ui64 ix=double2ui64(x),m;
 | 
				
			||||||
    int e=dgetexp(x);
 | 
					    int e=dgetexp(x);
 | 
				
			||||||
    if(e==0) {               // x==0
 | 
					    if(e==0) {               // x==0
 | 
				
			||||||
        ix&=0x8000000000000000ULL;
 | 
					        ix&=0x8000000000000000ULL;
 | 
				
			||||||
        return *(double*)&ix;
 | 
					        return ui642double(ix);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    e-=0x3ff;                // remove exponent bias
 | 
					    e-=0x3ff;                // remove exponent bias
 | 
				
			||||||
    if(e<0) {                // |x|<1, not zero
 | 
					    if(e<0) {                // |x|<1, not zero
 | 
				
			||||||
@ -219,16 +233,16 @@ double WRAPPER_FUNC(floor)(double x) {
 | 
				
			|||||||
    m=(1ULL<<e)-1;           // mask for bit of significance <1
 | 
					    m=(1ULL<<e)-1;           // mask for bit of significance <1
 | 
				
			||||||
    if(disneg(x)) ix+=m;     // add 1-ε to magnitude if negative
 | 
					    if(disneg(x)) ix+=m;     // add 1-ε to magnitude if negative
 | 
				
			||||||
    ix&=~m;                  // truncate
 | 
					    ix&=~m;                  // truncate
 | 
				
			||||||
    return *(double*)&ix;
 | 
					    return ui642double(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
double WRAPPER_FUNC(ceil)(double x) {
 | 
					double WRAPPER_FUNC(ceil)(double x) {
 | 
				
			||||||
    check_nan_d1(x);
 | 
					    check_nan_d1(x);
 | 
				
			||||||
    ui64 ix=*(ui64*)&x,m;
 | 
					    ui64 ix=double2ui64(x),m;
 | 
				
			||||||
    int e=dgetexp(x);
 | 
					    int e=dgetexp(x);
 | 
				
			||||||
    if(e==0) {               // x==0
 | 
					    if(e==0) {               // x==0
 | 
				
			||||||
        ix&=0x8000000000000000ULL;
 | 
					        ix&=0x8000000000000000ULL;
 | 
				
			||||||
        return *(double*)&ix;
 | 
					        return ui642double(ix);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    e-=0x3ff;                 // remove exponent bias
 | 
					    e-=0x3ff;                 // remove exponent bias
 | 
				
			||||||
    if(e<0) {                // |x|<1, not zero
 | 
					    if(e<0) {                // |x|<1, not zero
 | 
				
			||||||
@ -240,7 +254,7 @@ double WRAPPER_FUNC(ceil)(double x) {
 | 
				
			|||||||
    m=(1ULL<<e)-1;           // mask for bit of significance <1
 | 
					    m=(1ULL<<e)-1;           // mask for bit of significance <1
 | 
				
			||||||
    if(!disneg(x)) ix+=m;    // add 1-ε to magnitude if positive
 | 
					    if(!disneg(x)) ix+=m;    // add 1-ε to magnitude if positive
 | 
				
			||||||
    ix&=~m;                  // truncate
 | 
					    ix&=~m;                  // truncate
 | 
				
			||||||
    return *(double*)&ix;
 | 
					    return ui642double(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
double WRAPPER_FUNC(asin)(double x) {
 | 
					double WRAPPER_FUNC(asin)(double x) {
 | 
				
			||||||
@ -549,7 +563,7 @@ static i64 drem_0(i64 mx,i64 my,int e,int*pquo) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
double WRAPPER_FUNC(fmod)(double x,double y) {
 | 
					double WRAPPER_FUNC(fmod)(double x,double y) {
 | 
				
			||||||
    check_nan_d2(x, y);
 | 
					    check_nan_d2(x, y);
 | 
				
			||||||
    ui64 ix=*(ui64*)&x,iy=*(ui64*)&y;
 | 
					    ui64 ix=double2ui64(x),iy=double2ui64(y);
 | 
				
			||||||
    int sx,ex,ey;
 | 
					    int sx,ex,ey;
 | 
				
			||||||
    i64 mx,my;
 | 
					    i64 mx,my;
 | 
				
			||||||
    DUNPACKS(ix,sx,ex,mx);
 | 
					    DUNPACKS(ix,sx,ex,mx);
 | 
				
			||||||
@ -568,7 +582,7 @@ double WRAPPER_FUNC(fmod)(double x,double y) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
double WRAPPER_FUNC(remquo)(double x,double y,int*quo) {
 | 
					double WRAPPER_FUNC(remquo)(double x,double y,int*quo) {
 | 
				
			||||||
    check_nan_d2(x, y);
 | 
					    check_nan_d2(x, y);
 | 
				
			||||||
    ui64 ix=*(ui64*)&x,iy=*(ui64*)&y;
 | 
					    ui64 ix=double2ui64(x),iy=double2ui64(y);
 | 
				
			||||||
    int sx,sy,ex,ey,q;
 | 
					    int sx,sy,ex,ey,q;
 | 
				
			||||||
    i64 mx,my;
 | 
					    i64 mx,my;
 | 
				
			||||||
    DUNPACKS(ix,sx,ex,mx);
 | 
					    DUNPACKS(ix,sx,ex,mx);
 | 
				
			||||||
@ -609,5 +623,4 @@ double WRAPPER_FUNC(drem)(double x,double y) { check_nan_d2(x, y); return remquo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
double WRAPPER_FUNC(remainder)(double x,double y) { check_nan_d2(x, y); return remquo(x,y,0); }
 | 
					double WRAPPER_FUNC(remainder)(double x,double y) { check_nan_d2(x, y); return remquo(x,y,0); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_Pragma("GCC diagnostic pop") // strict-aliasing
 | 
					 | 
				
			||||||
_Pragma("GCC diagnostic pop") // conversion
 | 
					_Pragma("GCC diagnostic pop") // conversion
 | 
				
			||||||
@ -39,11 +39,25 @@ typedef int32_t i32;
 | 
				
			|||||||
#define FUNPACK(x,e,m) e=((x)>>23)&0xff,m=((x)&0x007fffff)|0x00800000
 | 
					#define FUNPACK(x,e,m) e=((x)>>23)&0xff,m=((x)&0x007fffff)|0x00800000
 | 
				
			||||||
#define FUNPACKS(x,s,e,m) s=((x)>>31),FUNPACK((x),(e),(m))
 | 
					#define FUNPACKS(x,s,e,m) s=((x)>>31),FUNPACK((x),(e),(m))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_Pragma("GCC diagnostic push")
 | 
					typedef union {
 | 
				
			||||||
_Pragma("GCC diagnostic ignored \"-Wstrict-aliasing\"")
 | 
					    float f;
 | 
				
			||||||
 | 
					    ui32 ix;
 | 
				
			||||||
 | 
					} float_ui32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline float ui322float(ui32 ix) {
 | 
				
			||||||
 | 
					    float_ui32 tmp;
 | 
				
			||||||
 | 
					    tmp.ix = ix;
 | 
				
			||||||
 | 
					    return tmp.f;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline ui32 float2ui32(float f) {
 | 
				
			||||||
 | 
					    float_ui32 tmp;
 | 
				
			||||||
 | 
					    tmp.f = f;
 | 
				
			||||||
 | 
					    return tmp.ix;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline bool fisnan(float x) {
 | 
					static inline bool fisnan(float x) {
 | 
				
			||||||
    ui32 ix=*(ui32*)&x;
 | 
					    ui32 ix=float2ui32(x);
 | 
				
			||||||
    return ix * 2 > 0xff000000u;
 | 
					    return ix * 2 > 0xff000000u;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -56,17 +70,17 @@ static inline bool fisnan(float x) {
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int fgetsignexp(float x) {
 | 
					static inline int fgetsignexp(float x) {
 | 
				
			||||||
    ui32 ix=*(ui32*)&x;
 | 
					    ui32 ix=float2ui32(x);
 | 
				
			||||||
    return (ix>>23)&0x1ff;
 | 
					    return (ix>>23)&0x1ff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int fgetexp(float x) {
 | 
					static inline int fgetexp(float x) {
 | 
				
			||||||
    ui32 ix=*(ui32*)&x;
 | 
					    ui32 ix=float2ui32(x);
 | 
				
			||||||
    return (ix>>23)&0xff;
 | 
					    return (ix>>23)&0xff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline float fldexp(float x,int de) {
 | 
					static inline float fldexp(float x,int de) {
 | 
				
			||||||
    ui32 ix=*(ui32*)&x,iy;
 | 
					    ui32 ix=float2ui32(x),iy;
 | 
				
			||||||
    int e;
 | 
					    int e;
 | 
				
			||||||
    e=fgetexp(x);
 | 
					    e=fgetexp(x);
 | 
				
			||||||
    if(e==0||e==0xff) return x;
 | 
					    if(e==0||e==0xff) return x;
 | 
				
			||||||
@ -74,7 +88,7 @@ static inline float fldexp(float x,int de) {
 | 
				
			|||||||
    if(e<=0) iy=ix&0x80000000; // signed zero for underflow
 | 
					    if(e<=0) iy=ix&0x80000000; // signed zero for underflow
 | 
				
			||||||
    else if(e>=0xff) iy=(ix&0x80000000)|0x7f800000ULL; // signed infinity on overflow
 | 
					    else if(e>=0xff) iy=(ix&0x80000000)|0x7f800000ULL; // signed infinity on overflow
 | 
				
			||||||
    else iy=ix+((ui32)de<<23);
 | 
					    else iy=ix+((ui32)de<<23);
 | 
				
			||||||
    return *(float*)&iy;
 | 
					    return ui322float(iy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float WRAPPER_FUNC(ldexpf)(float x, int de) {
 | 
					float WRAPPER_FUNC(ldexpf)(float x, int de) {
 | 
				
			||||||
@ -83,9 +97,9 @@ float WRAPPER_FUNC(ldexpf)(float x, int de) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline float fcopysign(float x,float y) {
 | 
					static inline float fcopysign(float x,float y) {
 | 
				
			||||||
    ui32 ix=*(ui32*)&x,iy=*(ui32*)&y;
 | 
					    ui32 ix=float2ui32(x),iy=float2ui32(y);
 | 
				
			||||||
    ix=((ix&0x7fffffff)|(iy&0x80000000));
 | 
					    ix=((ix&0x7fffffff)|(iy&0x80000000));
 | 
				
			||||||
    return *(float*)&ix;
 | 
					    return ui322float(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float WRAPPER_FUNC(copysignf)(float x, float y) {
 | 
					float WRAPPER_FUNC(copysignf)(float x, float y) {
 | 
				
			||||||
@ -101,7 +115,7 @@ static inline int fispinf(float x)  { return fgetsignexp(x)==0xff; }
 | 
				
			|||||||
static inline int fisminf(float x)  { return fgetsignexp(x)==0x1ff; }
 | 
					static inline int fisminf(float x)  { return fgetsignexp(x)==0x1ff; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int fisint(float x) {
 | 
					static inline int fisint(float x) {
 | 
				
			||||||
    ui32 ix=*(ui32*)&x,m;
 | 
					    ui32 ix=float2ui32(x),m;
 | 
				
			||||||
    int e=fgetexp(x);
 | 
					    int e=fgetexp(x);
 | 
				
			||||||
    if(e==0) return 1;       // 0 is an integer
 | 
					    if(e==0) return 1;       // 0 is an integer
 | 
				
			||||||
    e-=0x7f;                 // remove exponent bias
 | 
					    e-=0x7f;                 // remove exponent bias
 | 
				
			||||||
@ -114,7 +128,7 @@ static inline int fisint(float x) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int fisoddint(float x) {
 | 
					static inline int fisoddint(float x) {
 | 
				
			||||||
    ui32 ix=*(ui32*)&x,m;
 | 
					    ui32 ix=float2ui32(x),m;
 | 
				
			||||||
    int e=fgetexp(x);
 | 
					    int e=fgetexp(x);
 | 
				
			||||||
    e-=0x7f;                 // remove exponent bias
 | 
					    e-=0x7f;                 // remove exponent bias
 | 
				
			||||||
    if(e<0) return 0;        // |x|<1; 0 is not odd
 | 
					    if(e<0) return 0;        // |x|<1; 0 is not odd
 | 
				
			||||||
@ -127,24 +141,24 @@ static inline int fisoddint(float x) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int fisstrictneg(float x) {
 | 
					static inline int fisstrictneg(float x) {
 | 
				
			||||||
    ui32 ix=*(ui32*)&x;
 | 
					    ui32 ix=float2ui32(x);
 | 
				
			||||||
    if(fiszero(x)) return 0;
 | 
					    if(fiszero(x)) return 0;
 | 
				
			||||||
    return ix>>31;
 | 
					    return ix>>31;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int fisneg(float x) {
 | 
					static inline int fisneg(float x) {
 | 
				
			||||||
    ui32 ix=*(ui32*)&x;
 | 
					    ui32 ix=float2ui32(x);
 | 
				
			||||||
    return ix>>31;
 | 
					    return ix>>31;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline float fneg(float x) {
 | 
					static inline float fneg(float x) {
 | 
				
			||||||
    ui32 ix=*(ui32*)&x;
 | 
					    ui32 ix=float2ui32(x);
 | 
				
			||||||
    ix^=0x80000000;
 | 
					    ix^=0x80000000;
 | 
				
			||||||
    return *(float*)&ix;
 | 
					    return ui322float(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int fispo2(float x) {
 | 
					static inline int fispo2(float x) {
 | 
				
			||||||
    ui32 ix=*(ui32*)&x;
 | 
					    ui32 ix=float2ui32(x);
 | 
				
			||||||
    if(fiszero(x)) return 0;
 | 
					    if(fiszero(x)) return 0;
 | 
				
			||||||
    if(fisinf(x)) return 0;
 | 
					    if(fisinf(x)) return 0;
 | 
				
			||||||
    ix&=0x007fffff;
 | 
					    ix&=0x007fffff;
 | 
				
			||||||
@ -161,33 +175,33 @@ static inline float fnan_or(float x) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
float WRAPPER_FUNC(truncf)(float x) {
 | 
					float WRAPPER_FUNC(truncf)(float x) {
 | 
				
			||||||
    check_nan_f1(x);
 | 
					    check_nan_f1(x);
 | 
				
			||||||
    ui32 ix=*(ui32*)&x,m;
 | 
					    ui32 ix=float2ui32(x),m;
 | 
				
			||||||
    int e=fgetexp(x);
 | 
					    int e=fgetexp(x);
 | 
				
			||||||
    e-=0x7f;                 // remove exponent bias
 | 
					    e-=0x7f;                 // remove exponent bias
 | 
				
			||||||
    if(e<0) {                // |x|<1
 | 
					    if(e<0) {                // |x|<1
 | 
				
			||||||
        ix&=0x80000000;
 | 
					        ix&=0x80000000;
 | 
				
			||||||
        return *(float*)&ix;
 | 
					        return ui322float(ix);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    e=23-e;                  // bit position in mantissa with significance 1
 | 
					    e=23-e;                  // bit position in mantissa with significance 1
 | 
				
			||||||
    if(e<=0) return x;       // |x| large, so must be an integer
 | 
					    if(e<=0) return x;       // |x| large, so must be an integer
 | 
				
			||||||
    m=(1<<e)-1;              // mask for bits of significance <1
 | 
					    m=(1<<e)-1;              // mask for bits of significance <1
 | 
				
			||||||
    ix&=~m;
 | 
					    ix&=~m;
 | 
				
			||||||
    return *(float*)&ix;
 | 
					    return ui322float(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float WRAPPER_FUNC(roundf)(float x) {
 | 
					float WRAPPER_FUNC(roundf)(float x) {
 | 
				
			||||||
    check_nan_f1(x);
 | 
					    check_nan_f1(x);
 | 
				
			||||||
    ui32 ix=*(ui32*)&x,m;
 | 
					    ui32 ix=float2ui32(x),m;
 | 
				
			||||||
    int e=fgetexp(x);
 | 
					    int e=fgetexp(x);
 | 
				
			||||||
    e-=0x7f;                 // remove exponent bias
 | 
					    e-=0x7f;                 // remove exponent bias
 | 
				
			||||||
    if(e<-1) {               // |x|<0.5
 | 
					    if(e<-1) {               // |x|<0.5
 | 
				
			||||||
        ix&=0x80000000;
 | 
					        ix&=0x80000000;
 | 
				
			||||||
        return *(float*)&ix;
 | 
					        return ui322float(ix);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(e==-1) {              // 0.5<=|x|<1
 | 
					    if(e==-1) {              // 0.5<=|x|<1
 | 
				
			||||||
        ix&=0x80000000;
 | 
					        ix&=0x80000000;
 | 
				
			||||||
        ix|=0x3f800000;        // ±1
 | 
					        ix|=0x3f800000;        // ±1
 | 
				
			||||||
        return *(float*)&ix;
 | 
					        return ui322float(ix);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    e=23-e;                  // bit position in mantissa with significance 1, <=23
 | 
					    e=23-e;                  // bit position in mantissa with significance 1, <=23
 | 
				
			||||||
    if(e<=0) return x;       // |x| large, so must be an integer
 | 
					    if(e<=0) return x;       // |x| large, so must be an integer
 | 
				
			||||||
@ -195,16 +209,16 @@ float WRAPPER_FUNC(roundf)(float x) {
 | 
				
			|||||||
    ix+=m;
 | 
					    ix+=m;
 | 
				
			||||||
    m=m+m-1;                 // mask for bits of significance <1
 | 
					    m=m+m-1;                 // mask for bits of significance <1
 | 
				
			||||||
    ix&=~m;
 | 
					    ix&=~m;
 | 
				
			||||||
    return *(float*)&ix;
 | 
					    return ui322float(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float WRAPPER_FUNC(floorf)(float x) {
 | 
					float WRAPPER_FUNC(floorf)(float x) {
 | 
				
			||||||
    check_nan_f1(x);
 | 
					    check_nan_f1(x);
 | 
				
			||||||
    ui32 ix=*(ui32*)&x,m;
 | 
					    ui32 ix=float2ui32(x),m;
 | 
				
			||||||
    int e=fgetexp(x);
 | 
					    int e=fgetexp(x);
 | 
				
			||||||
    if(e==0) {       // x==0
 | 
					    if(e==0) {       // x==0
 | 
				
			||||||
        ix&=0x80000000;
 | 
					        ix&=0x80000000;
 | 
				
			||||||
        return *(float*)&ix;
 | 
					        return ui322float(ix);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    e-=0x7f;                 // remove exponent bias
 | 
					    e-=0x7f;                 // remove exponent bias
 | 
				
			||||||
    if(e<0) {                // |x|<1, not zero
 | 
					    if(e<0) {                // |x|<1, not zero
 | 
				
			||||||
@ -216,16 +230,16 @@ float WRAPPER_FUNC(floorf)(float x) {
 | 
				
			|||||||
    m=(1<<e)-1;              // mask for bit of significance <1
 | 
					    m=(1<<e)-1;              // mask for bit of significance <1
 | 
				
			||||||
    if(fisneg(x)) ix+=m;     // add 1-ε to magnitude if negative
 | 
					    if(fisneg(x)) ix+=m;     // add 1-ε to magnitude if negative
 | 
				
			||||||
    ix&=~m;                  // truncate
 | 
					    ix&=~m;                  // truncate
 | 
				
			||||||
    return *(float*)&ix;
 | 
					    return ui322float(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float WRAPPER_FUNC(ceilf)(float x) {
 | 
					float WRAPPER_FUNC(ceilf)(float x) {
 | 
				
			||||||
    check_nan_f1(x);
 | 
					    check_nan_f1(x);
 | 
				
			||||||
    ui32 ix=*(ui32*)&x,m;
 | 
					    ui32 ix=float2ui32(x),m;
 | 
				
			||||||
    int e=fgetexp(x);
 | 
					    int e=fgetexp(x);
 | 
				
			||||||
    if(e==0) {       // x==0
 | 
					    if(e==0) {       // x==0
 | 
				
			||||||
        ix&=0x80000000;
 | 
					        ix&=0x80000000;
 | 
				
			||||||
        return *(float*)&ix;
 | 
					        return ui322float(ix);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    e-=0x7f;                 // remove exponent bias
 | 
					    e-=0x7f;                 // remove exponent bias
 | 
				
			||||||
    if(e<0) {                // |x|<1, not zero
 | 
					    if(e<0) {                // |x|<1, not zero
 | 
				
			||||||
@ -237,7 +251,7 @@ float WRAPPER_FUNC(ceilf)(float x) {
 | 
				
			|||||||
    m=(1<<e)-1;              // mask for bit of significance <1
 | 
					    m=(1<<e)-1;              // mask for bit of significance <1
 | 
				
			||||||
    if(!fisneg(x)) ix+=m;    // add 1-ε to magnitude if positive
 | 
					    if(!fisneg(x)) ix+=m;    // add 1-ε to magnitude if positive
 | 
				
			||||||
    ix&=~m;                  // truncate
 | 
					    ix&=~m;                  // truncate
 | 
				
			||||||
    return *(float*)&ix;
 | 
					    return ui322float(ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float WRAPPER_FUNC(asinf)(float x) {
 | 
					float WRAPPER_FUNC(asinf)(float x) {
 | 
				
			||||||
@ -505,7 +519,7 @@ static i32 frem_0(i32 mx,i32 my,int e,int*pquo) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
float WRAPPER_FUNC(fmodf)(float x,float y) {
 | 
					float WRAPPER_FUNC(fmodf)(float x,float y) {
 | 
				
			||||||
    check_nan_f2(x,y);
 | 
					    check_nan_f2(x,y);
 | 
				
			||||||
    ui32 ix=*(ui32*)&x,iy=*(ui32*)&y;
 | 
					    ui32 ix=float2ui32(x),iy=float2ui32(y);
 | 
				
			||||||
    int sx,ex,ey;
 | 
					    int sx,ex,ey;
 | 
				
			||||||
    i32 mx,my;
 | 
					    i32 mx,my;
 | 
				
			||||||
    FUNPACKS(ix,sx,ex,mx);
 | 
					    FUNPACKS(ix,sx,ex,mx);
 | 
				
			||||||
@ -526,7 +540,7 @@ float WRAPPER_FUNC(fmodf)(float x,float y) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
float WRAPPER_FUNC(remquof)(float x,float y,int*quo) {
 | 
					float WRAPPER_FUNC(remquof)(float x,float y,int*quo) {
 | 
				
			||||||
    check_nan_f2(x,y);
 | 
					    check_nan_f2(x,y);
 | 
				
			||||||
    ui32 ix=*(ui32*)&x,iy=*(ui32*)&y;
 | 
					    ui32 ix=float2ui32(x),iy=float2ui32(y);
 | 
				
			||||||
    int sx,sy,ex,ey,q;
 | 
					    int sx,sy,ex,ey,q;
 | 
				
			||||||
    i32 mx,my;
 | 
					    i32 mx,my;
 | 
				
			||||||
    FUNPACKS(ix,sx,ex,mx);
 | 
					    FUNPACKS(ix,sx,ex,mx);
 | 
				
			||||||
@ -567,5 +581,4 @@ float WRAPPER_FUNC(dremf)(float x,float y) { check_nan_f2(x,y); return remquof(x
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
float WRAPPER_FUNC(remainderf)(float x,float y) { check_nan_f2(x,y); return remquof(x,y,0); }
 | 
					float WRAPPER_FUNC(remainderf)(float x,float y) { check_nan_f2(x,y); return remquof(x,y,0); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_Pragma("GCC diagnostic pop") // strict-aliasing
 | 
					 | 
				
			||||||
_Pragma("GCC diagnostic pop") // conversion
 | 
					_Pragma("GCC diagnostic pop") // conversion
 | 
				
			||||||
		Reference in New Issue
	
	Block a user