MathUtil: add constructors to IntFloat/IntDouble

This commit is contained in:
Tillmann Karras 2014-03-23 10:24:06 +01:00
parent 9849129b5d
commit af525266d4
2 changed files with 14 additions and 10 deletions

View File

@ -15,8 +15,7 @@ namespace MathUtil
u32 ClassifyDouble(double dvalue) u32 ClassifyDouble(double dvalue)
{ {
// TODO: Optimize the below to be as fast as possible. // TODO: Optimize the below to be as fast as possible.
IntDouble value; IntDouble value(dvalue);
value.d = dvalue;
u64 sign = value.i & DOUBLE_SIGN; u64 sign = value.i & DOUBLE_SIGN;
u64 exp = value.i & DOUBLE_EXP; u64 exp = value.i & DOUBLE_EXP;
if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP) if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP)
@ -55,8 +54,7 @@ u32 ClassifyDouble(double dvalue)
u32 ClassifyFloat(float fvalue) u32 ClassifyFloat(float fvalue)
{ {
// TODO: Optimize the below to be as fast as possible. // TODO: Optimize the below to be as fast as possible.
IntFloat value; IntFloat value(fvalue);
value.f = fvalue;
u32 sign = value.i & FLOAT_SIGN; u32 sign = value.i & FLOAT_SIGN;
u32 exp = value.i & FLOAT_EXP; u32 exp = value.i & FLOAT_EXP;
if (exp > FLOAT_ZERO && exp < FLOAT_EXP) if (exp > FLOAT_ZERO && exp < FLOAT_EXP)

View File

@ -36,35 +36,41 @@ static const u32 FLOAT_SIGN = 0x80000000,
union IntDouble { union IntDouble {
double d; double d;
u64 i; u64 i;
explicit IntDouble(u64 _i) : i(_i) {}
explicit IntDouble(double _d) : d(_d) {}
}; };
union IntFloat { union IntFloat {
float f; float f;
u32 i; u32 i;
explicit IntFloat(u32 _i) : i(_i) {}
explicit IntFloat(float _f) : f(_f) {}
}; };
inline bool IsINF(double d) inline bool IsINF(double d)
{ {
IntDouble x; x.d = d; IntDouble x(d);
return (x.i & ~DOUBLE_SIGN) == DOUBLE_EXP; return (x.i & ~DOUBLE_SIGN) == DOUBLE_EXP;
} }
inline bool IsNAN(double d) inline bool IsNAN(double d)
{ {
IntDouble x; x.d = d; IntDouble x(d);
return ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && return ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
((x.i & DOUBLE_FRAC) != DOUBLE_ZERO); ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO);
} }
inline bool IsQNAN(double d) inline bool IsQNAN(double d)
{ {
IntDouble x; x.d = d; IntDouble x(d);
return ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && return ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
((x.i & DOUBLE_QBIT) == DOUBLE_QBIT); ((x.i & DOUBLE_QBIT) == DOUBLE_QBIT);
} }
inline bool IsSNAN(double d) inline bool IsSNAN(double d)
{ {
IntDouble x; x.d = d; IntDouble x(d);
return ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && return ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) && ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) &&
((x.i & DOUBLE_QBIT) == DOUBLE_ZERO); ((x.i & DOUBLE_QBIT) == DOUBLE_ZERO);
@ -72,7 +78,7 @@ inline bool IsSNAN(double d)
inline float FlushToZero(float f) inline float FlushToZero(float f)
{ {
IntFloat x; x.f = f; IntFloat x(f);
if ((x.i & FLOAT_EXP) == 0) if ((x.i & FLOAT_EXP) == 0)
{ {
x.i &= FLOAT_SIGN; // turn into signed zero x.i &= FLOAT_SIGN; // turn into signed zero
@ -82,7 +88,7 @@ inline float FlushToZero(float f)
inline double FlushToZero(double d) inline double FlushToZero(double d)
{ {
IntDouble x; x.d = d; IntDouble x(d);
if ((x.i & DOUBLE_EXP) == 0) if ((x.i & DOUBLE_EXP) == 0)
{ {
x.i &= DOUBLE_SIGN; // turn into signed zero x.i &= DOUBLE_SIGN; // turn into signed zero