Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

341 lines
10 KiB

/******************************Module*Header*******************************\
* Module Name: efloat.hxx *
* *
* Contains internal floating point objects and methods. *
* *
* Created: 12-Nov-1990 16:45:01 *
* Author: Wendy Wu [wendywu] *
* *
* Copyright (c) 1990 Microsoft Corporation *
\**************************************************************************/
#define BOOL_TRUNCATE 0
#define BOOL_ROUND 1
class EFLOAT;
extern "C" {
BOOL eftol_c(EFLOAT *, PLONG, LONG);
BOOL eftofx_c(EFLOAT *, PFIX);
LONG eftof_c(EFLOAT *);
VOID ltoef_c(LONG, EFLOAT *);
VOID fxtoef_c(FIX, EFLOAT *);
VOID ftoef_c(FLOAT, EFLOAT *);
// New style floating point support routines. The first pointer specifies
// where to put the return value. The first pointer is the return value.
EFLOAT *addff3_c(EFLOAT *,EFLOAT *,EFLOAT *);
EFLOAT *subff3_c(EFLOAT *,EFLOAT *,EFLOAT *);
EFLOAT *mulff3_c(EFLOAT *,const EFLOAT *,const EFLOAT *);
EFLOAT *divff3_c(EFLOAT *,EFLOAT *,EFLOAT *);
EFLOAT *sqrtf2_c(const EFLOAT *,const EFLOAT *);
EFLOAT *fraction_c(EFLOAT *,EFLOAT *);
};
class POINTFL;
/*********************************Class************************************\
* class EFLOAT *
* *
* Energized floating point object. *
* *
* The floating point object defined below has 32 bits of signed mantissa *
* and 16 bits of signed exponent. The decimal point is before the MSB *
* of mantissa. The value of a number is determined by the following *
* equation: *
* value = 0.mantissa * 2^exponent *
* *
* Zero has only one unique representation with mantissa and exponent both *
* zero. *
* *
* History: *
* 12-Nov-1990 -by- Wendy Wu [wendywu] *
* Wrote it. *
\**************************************************************************/
class EFLOAT
{
public: // has to be public in order for
EFLOAT_S i; // MAKEEFLOAT to do initializations
public:
EFLOAT_S Base() {return(i);}
// Operator+= -- Add two EFLOAT numbers together. Caller is responsible for
// overflow checking.
VOID operator+=(EFLOAT& ef) {addff3_c(this,this,&ef);}
// Operator-= -- Substract an EFLOAT number from another. Caller is
// responsible for overflow checkings.
VOID operator-=(EFLOAT& ef) {subff3_c(this,this,&ef);}
// Operator*= -- Multiply two EFLOAT numbers together. Caller is responsible for
// overflow checkings.
VOID operator*=(EFLOAT& ef) {mulff3_c(this,this,&ef);}
// vTimes16 -- Multiply an EFLOAT number by 16.
VOID vTimes16() { if (i.lMant != 0) i.lExp += 4; }
// Operator/ -- Divide an EFLOAT number by another. Caller is responsible for
// overflow checkings.
VOID operator/=(EFLOAT& ef) {divff3_c(this,this,&ef);}
// vDivBy16 -- Divide an EFLOAT number by 16.
VOID vDivBy16() { if (i.lMant != 0) i.lExp -= 4; }
// vNegate - Negate an EFLOAT number.
VOID vNegate()
{
if (i.lMant != 0x80000000)
i.lMant = -i.lMant;
else
{
i.lMant = 0x40000000;
i.lExp += 1;
}
}
// operator> -- Signed compare two numbers. See if an EFLOAT number is
// greater than a given number.
// Is there a better way to do this???
BOOL operator>(EFLOAT& ef)
{
LONG lsignSrc = ef.i.lMant >> 31, lsignDest = i.lMant >> 31;
BOOL bReturn = FALSE;
if (lsignSrc < lsignDest) // src is negative, dest is positive
bReturn = TRUE;
else if (lsignSrc > lsignDest) // src is positive, dest is negative
;
else if (i.lExp == ef.i.lExp) // same sign, same exp, comp mantissa
bReturn = i.lMant > ef.i.lMant;
else if (lsignSrc == 0) // both src and dest are positive
{
if (((i.lExp > ef.i.lExp) && (i.lMant != 0)) || ef.i.lMant == 0)
bReturn = TRUE;
}
else // both negative
{
if (i.lExp < ef.i.lExp) // zero won't reach here
bReturn = TRUE;
}
return bReturn;
}
// operator<=,>,>=,== -- Compare two EFLOAT numbers.
BOOL operator<=(EFLOAT& ef) { return(!((*this) > ef)); }
BOOL operator<(EFLOAT& ef) { return(ef > (*this)); }
BOOL operator>=(EFLOAT& ef) { return(ef <= (*this)); }
BOOL operator==(EFLOAT& ef)
{
return((i.lMant == ef.i.lMant) && (i.lExp == ef.i.lExp));
}
// Operator= -- Assign a value to an EFLOAT number.
VOID operator=(LONG l) {ltoef_c(l,this);}
VOID operator=(FLOAT f) {ftoef_c(f,this);}
// vFxToEf -- Convert a FIX number to an EFLOAT number.
// This could have been another operator=(FIX fx). However, since
// FIX is defined as LONG. The compiler doesn't accept the second
// definition.
VOID vFxToEf(FIX fx) {fxtoef_c(fx,this);}
// bEfToL -- Convert an EFLOAT number to a LONG integer. Fractions of 0.5 or
// greater are rounded up.
BOOL bEfToL(LONG &l) { return(eftol_c(this, &l, BOOL_ROUND)); }
// bEfToLTruncate -- Convert an EFLOAT number to a LONG integer. The fractions
// are truncated.
BOOL bEfToLTruncate(LONG &l){ return(eftol_c(this, &l, BOOL_TRUNCATE)); }
// lEfToF -- Convert an EFLOAT number to an IEEE FLOAT number. The return
// value is placed in eax. We want to treat it as a LONG to
// avoid any fstp later.
LONG lEfToF() { return(eftof_c(this)); }
VOID vEfToF(FLOAT &e) { LONG l = eftof_c(this); e = *((PFLOAT) (&l)); }
// bEfToFx -- Convert an EFLOAT number to a FIX number.
BOOL bEfToFx(FIX &fx) { return(eftofx_c(this, &fx)); }
// bIsZero -- See if an EFLOAT number is zero.
BOOL bIsZero() { return((i.lMant == 0) && (i.lExp == 0)); }
// bIs16 -- Quick way to check the value of an EFLOAT number.
BOOL bIs16() { return((i.lMant == 0x040000000) && (i.lExp == 6)); }
BOOL bIsNeg16() { return((i.lMant == 0x0c0000000) && (i.lExp == 6)); }
BOOL bIs1() { return((i.lMant == 0x040000000) && (i.lExp == 2)); }
BOOL bIsNeg1() { return((i.lMant == 0x0c0000000) && (i.lExp == 2)); }
BOOL bIs1Over16() { return((i.lMant == 0x040000000) && (i.lExp == -2)); }
BOOL bIsNeg1Over16() { return((i.lMant == 0x0c0000000) && (i.lExp == -2)); }
// vDivBy2 -- Divide an EFLOAT number by 2.
VOID vDivBy2() { i.lExp -= 1; }
VOID vMultByPowerOf2(INT ii) { i.lExp += (LONG) ii; }
// vSetToZero -- Set the value of an EFLOAT number to zero.
VOID vSetToZero() { i.lMant = 0; i.lExp = 0; }
// vSetToOne -- Set the value of an EFLOAT number to one.
VOID vSetToOne() {i.lMant=0x040000000; i.lExp=2;}
// bIsNegative -- See if an EFLOAT number is negative.
BOOL bIsNegative() { return(i.lMant < 0); }
// signum -- Return a LONG representing the sign of the number.
LONG lSignum() {return((i.lMant > 0) - (i.lMant < 0));}
// vAbs -- Compute the absolute value.
VOID vAbs() { if (bIsNegative()) vNegate(); }
// vFraction -- Get the fraction part of an EFLOAT number. The result is
// stored in the passed in parameter.
//!!! This looks backwards. [chuckwh]
VOID vFraction(EFLOAT& ef) {fraction_c(&ef,this);}
// bExpInRange -- See if the exponent of an EFLOAT number is within the
// given range.
BOOL bExpLessThan(LONG max)
{
return(i.lExp <=max);
}
// vSqrt -- Takes the square root.
VOID vSqrt() {sqrtf2_c(this,this);}
// New style math routines.
//
// Usage example: EFLOAT z,t; z.eqAdd(x,t.eqSqrt(y));
// This would be the same as: EFLOAT z,t; z = x + (t = sqrt(y));
//
// I.e. you can build complex expressions, but you must declare your own
// temporaries.
EFLOAT& eqSqrt(const EFLOAT& ef)
{
return(*sqrtf2_c(this,&ef));
}
EFLOAT& eqAdd(EFLOAT& efA,EFLOAT& efB)
{
return(*addff3_c(this,&efA,&efB));
}
EFLOAT& eqSub(EFLOAT& efA,EFLOAT& efB)
{
return(*subff3_c(this,&efA,&efB));
}
EFLOAT& eqMul(const EFLOAT& efA,const EFLOAT& efB)
{
return(*mulff3_c(this,&efA,&efB));
}
EFLOAT& eqDiv(EFLOAT& efA,EFLOAT& efB)
{
return(*divff3_c(this,&efA,&efB));
}
EFLOAT& eqFraction(EFLOAT& ef)
{
return(*fraction_c(this,&ef));
}
EFLOAT& eqAbs(EFLOAT& ef)
{
i.lExp = ef.i.lExp;
i.lMant = ef.i.lMant;
if (i.lMant < 0)
{
if (i.lMant != 0x80000000)
{
i.lMant = -i.lMant;
}
else
{
i.lMant = 0x40000000;
i.lExp++;
}
}
return(*this);
}
// eqDot -- Dot product of two vectors.
EFLOAT eqDot(const POINTFL&,const POINTFL&);
// eqCross -- Cross product of two vectors. (A scaler in 2 dimensions.)
EFLOAT eqCross(const POINTFL&,const POINTFL&);
// eqLength -- Length of a vector.
EFLOAT eqLength(const POINTFL&);
};
class EFLOATEXT: public EFLOAT {
public:
EFLOATEXT() {}
EFLOATEXT(LONG l) {ltoef_c(l,this);}
EFLOATEXT(FLOAT e) {ftoef_c(e,this);}
VOID operator=(const EFLOAT& ef) {*(EFLOAT*) this = ef;}
VOID operator=(LONG l) {*(EFLOAT*) this = l;}
VOID operator*=(LONG l)
{
EFLOATEXT efT(l);
mulff3_c(this,this,&efT);
}
VOID operator*=(EFLOAT& ef)
{
*(EFLOAT*)this *= ef;
}
VOID operator/=(EFLOAT& ef)
{
*(EFLOAT*)this /= ef;
}
VOID operator/=(LONG l)
{
EFLOATEXT efT(l);
divff3_c(this,this,&efT);
}
};
extern "C" LONG lCvt(EFLOAT ef,LONG ll);