windows-nt/Source/XPSP1/NT/drivers/tpg/hwx/commonu/inc/math16.h

82 lines
2.4 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
#ifndef __MATH16_H__
#define __MATH16_H__
#ifdef __cplusplus
extern "C" {
#endif
// Type for fixed point 16.16 numbers. I used LONG as the base type because it is the only
// type I could find guarantied to stay a 32 bit signed number, even when we convert to
// 64 bit machines.
typedef LONG FIXED16_16;
// Constants for dealing with shifting the bits around in the 16.16 format.
#define SHFTBITS 16
#define LOWMASK ((1 << SHFTBITS)-1)
#define HGHMASK (~LOWMASK)
#define LOWBITS(x) ((x) & LOWMASK)
#define HGHBITS(x) ((x) & HGHMASK)
#define LSHFT(x) ((x) << SHFTBITS)
#define RSHFT(x) ((x) >> SHFTBITS)
// Useful constants in 16.16 form
#define PI (3373259427 >> (30-SHFTBITS))
#define TWOPI (PI << 1)
#define PIOVER2 (PI >> 1)
#define ONE_POINT_ZERO 0x00010000 // (1 << SHFTBITS), but prefast complains when cast to double
// How many bits needed to store a number.
#define Need(dw) (dw & 0xFF000000 ? 32 : (dw & 0x00FF0000 ? 24 : (dw & 0x0000FF00 ? 16 : 8)))
// Convert number to 16.16 form.
#define IntToFix16(val) (((FIXED16_16)(val)) << SHFTBITS)
#define FloatToFix16(val) ((FIXED16_16)((val) * (double)ONE_POINT_ZERO))
// Convert 16.16 form to a number.
#define Fix16ToInt(val) RSHFT(val)
#define Fix16ToFloat(val) ((val) / (double)ONE_POINT_ZERO)
// Convert other fixed point forms to a double.
// If the value of N (number of fractional bits) is a constant, this is much faster then shifting
// and using Fix16ToFloat. If N is a variable, the 64 bit shift is very expensive.
#define FixNToFloat(val, n) ((val) / (double)((_int64)1 << n))
// Compute a sigmoid on a 16.16 number.
FIXED16_16 Sigmoid16(FIXED16_16 iX);
// Add two 16.16 numbers. We just do the macro for clearity and documentation, because
// add just works.
#define Add16(iX, iY) (iX + iY)
// The same for subtraction.
#define Sub16(iX, iY) (iX - iY)
// Dived two 16.16 numbers.
FIXED16_16 Div16(FIXED16_16 iX, FIXED16_16 iY);
// Multiply two 16.16 numbers. This uses Greg's multiplication algorithm:
typedef struct {
unsigned short frac;
short whole;
} FIX1616, *PFIX1616;
#define Mul16(a,b,c) { \
FIXED16_16 i1, i2; \
FIX1616 fix1, fix2; \
i1=(a); \
i2=(b); \
fix1 = *(PFIX1616)&i1; \
fix2 = *(PFIX1616)&i2; \
c = (DWORD)(fix1.frac*fix2.frac) >> 16; \
c += fix1.frac*fix2.whole + fix1.whole*fix2.frac; \
c += (fix1.whole*fix2.whole) << 16; \
}
#ifdef __cplusplus
}
#endif
#endif // __MATH16_H__