Source code of Windows XP (NT5)
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.

81 lines
2.4 KiB

  1. #ifndef __MATH16_H__
  2. #define __MATH16_H__
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. // Type for fixed point 16.16 numbers. I used LONG as the base type because it is the only
  7. // type I could find guarantied to stay a 32 bit signed number, even when we convert to
  8. // 64 bit machines.
  9. typedef LONG FIXED16_16;
  10. // Constants for dealing with shifting the bits around in the 16.16 format.
  11. #define SHFTBITS 16
  12. #define LOWMASK ((1 << SHFTBITS)-1)
  13. #define HGHMASK (~LOWMASK)
  14. #define LOWBITS(x) ((x) & LOWMASK)
  15. #define HGHBITS(x) ((x) & HGHMASK)
  16. #define LSHFT(x) ((x) << SHFTBITS)
  17. #define RSHFT(x) ((x) >> SHFTBITS)
  18. // Useful constants in 16.16 form
  19. #define PI (3373259427 >> (30-SHFTBITS))
  20. #define TWOPI (PI << 1)
  21. #define PIOVER2 (PI >> 1)
  22. #define ONE_POINT_ZERO 0x00010000 // (1 << SHFTBITS), but prefast complains when cast to double
  23. // How many bits needed to store a number.
  24. #define Need(dw) (dw & 0xFF000000 ? 32 : (dw & 0x00FF0000 ? 24 : (dw & 0x0000FF00 ? 16 : 8)))
  25. // Convert number to 16.16 form.
  26. #define IntToFix16(val) (((FIXED16_16)(val)) << SHFTBITS)
  27. #define FloatToFix16(val) ((FIXED16_16)((val) * (double)ONE_POINT_ZERO))
  28. // Convert 16.16 form to a number.
  29. #define Fix16ToInt(val) RSHFT(val)
  30. #define Fix16ToFloat(val) ((val) / (double)ONE_POINT_ZERO)
  31. // Convert other fixed point forms to a double.
  32. // If the value of N (number of fractional bits) is a constant, this is much faster then shifting
  33. // and using Fix16ToFloat. If N is a variable, the 64 bit shift is very expensive.
  34. #define FixNToFloat(val, n) ((val) / (double)((_int64)1 << n))
  35. // Compute a sigmoid on a 16.16 number.
  36. FIXED16_16 Sigmoid16(FIXED16_16 iX);
  37. // Add two 16.16 numbers. We just do the macro for clearity and documentation, because
  38. // add just works.
  39. #define Add16(iX, iY) (iX + iY)
  40. // The same for subtraction.
  41. #define Sub16(iX, iY) (iX - iY)
  42. // Dived two 16.16 numbers.
  43. FIXED16_16 Div16(FIXED16_16 iX, FIXED16_16 iY);
  44. // Multiply two 16.16 numbers. This uses Greg's multiplication algorithm:
  45. typedef struct {
  46. unsigned short frac;
  47. short whole;
  48. } FIX1616, *PFIX1616;
  49. #define Mul16(a,b,c) { \
  50. FIXED16_16 i1, i2; \
  51. FIX1616 fix1, fix2; \
  52. i1=(a); \
  53. i2=(b); \
  54. fix1 = *(PFIX1616)&i1; \
  55. fix2 = *(PFIX1616)&i2; \
  56. c = (DWORD)(fix1.frac*fix2.frac) >> 16; \
  57. c += fix1.frac*fix2.whole + fix1.whole*fix2.frac; \
  58. c += (fix1.whole*fix2.whole) << 16; \
  59. }
  60. #ifdef __cplusplus
  61. }
  62. #endif
  63. #endif // __MATH16_H__