1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #ifndef FIXED_POINT_HH
|
---|
10 | #define FIXED_POINT_HH
|
---|
11 |
|
---|
12 | #include "arch.hh"
|
---|
13 |
|
---|
14 | template <class ca, class cb>
|
---|
15 | inline ca i4_fixed_point_convert(ca &a, cb b)
|
---|
16 | // convert between fixed point precisions
|
---|
17 | //{{{
|
---|
18 | {
|
---|
19 | return (a = ca(b.real(), b.fraction()));
|
---|
20 | }
|
---|
21 | //}}}
|
---|
22 |
|
---|
23 | template <int precision>
|
---|
24 | class i4_fixed_point
|
---|
25 | {
|
---|
26 | protected:
|
---|
27 | i4_fixed_point(sw32 a, int dummy, int dummy2) : value(a) {}
|
---|
28 | //{{{ Notes:
|
---|
29 | // dummy parameters used to allow for standard constructors
|
---|
30 | // I'm hoping that the compiler will be smart enough to drop code for the dummies
|
---|
31 | //}}}
|
---|
32 |
|
---|
33 | #define DIRECT_CAST(a) i4_fixed_point(a,0,0)
|
---|
34 | public:
|
---|
35 | sw32 value;
|
---|
36 |
|
---|
37 | i4_fixed_point() {}
|
---|
38 | i4_fixed_point(const sw32 r, const w32 f) : value((r<<precision) | (f>>(32-precision))) {}
|
---|
39 |
|
---|
40 | //{{{ Standard Type conversions
|
---|
41 | i4_fixed_point(const int a) : value(sw32(a)<<precision) {}
|
---|
42 | i4_fixed_point(const unsigned int a) : value(sw32(a)<<precision) {}
|
---|
43 | i4_fixed_point(const sw8 a) : value(sw32(a)<<precision) {}
|
---|
44 | i4_fixed_point(const w8 a) : value(sw32(a)<<precision) {}
|
---|
45 | i4_fixed_point(const sw16 a) : value(sw32(a)<<precision) {}
|
---|
46 | i4_fixed_point(const w16 a) : value(sw32(a)<<precision) {}
|
---|
47 | i4_fixed_point(const sw32 a) : value(a<<precision) {}
|
---|
48 | i4_fixed_point(const w32 a) : value(a<<precision) {}
|
---|
49 | i4_fixed_point(const float a) : value(sw32(a*float(1<<precision))) {}
|
---|
50 | i4_fixed_point(const double a) : value(sw32(a*double(1<<precision))) {}
|
---|
51 |
|
---|
52 | operator int() const { return int(value>>precision); }
|
---|
53 | operator unsigned int() const { return int(((w32)value)>>precision); }
|
---|
54 | operator sw8() const { return sw8(value>>precision); }
|
---|
55 | operator w8() const { return w8(((w32)value)>>precision); }
|
---|
56 | operator sw16() const { return sw16(value>>precision); }
|
---|
57 | operator w16() const { return w16(((w32)value)>>precision); }
|
---|
58 | operator sw32() const { return value>>precision; }
|
---|
59 | operator w32() const { return ((w32)value)>>precision; }
|
---|
60 | operator double() const { return double(value)/double(1<<precision); }
|
---|
61 | operator float() const { return float(value)/float(1<<precision); }
|
---|
62 | //}}}
|
---|
63 |
|
---|
64 | i4_fixed_point operator+(const i4_fixed_point b) const { return DIRECT_CAST(value + b.value); }
|
---|
65 | i4_fixed_point operator-(const i4_fixed_point b) const { return DIRECT_CAST(value - b.value); }
|
---|
66 | i4_fixed_point operator*(const i4_fixed_point b) const
|
---|
67 | //{{{
|
---|
68 | {
|
---|
69 | return DIRECT_CAST((value * b.value)>>precision);
|
---|
70 | }
|
---|
71 | //}}}
|
---|
72 | i4_fixed_point operator/(const i4_fixed_point b) const
|
---|
73 | //{{{
|
---|
74 | {
|
---|
75 | return DIRECT_CAST((value<<precision) / b.value);
|
---|
76 | }
|
---|
77 | //}}}
|
---|
78 |
|
---|
79 | i4_fixed_point divide(const i4_fixed_point b, const int div_imprec = 0) const
|
---|
80 | //{{{
|
---|
81 | // imprecise divide to avoid overflows
|
---|
82 | {
|
---|
83 | return DIRECT_CAST((value<<(precision-div_imprec)) / (b.value>>div_imprec));
|
---|
84 | }
|
---|
85 | //}}}
|
---|
86 |
|
---|
87 | i4_fixed_point operator= (const i4_fixed_point b) { return DIRECT_CAST(value = b.value); }
|
---|
88 | i4_fixed_point operator+=(const i4_fixed_point b) { return DIRECT_CAST(value += b.value); }
|
---|
89 | i4_fixed_point operator-=(const i4_fixed_point b) { return DIRECT_CAST(value -= b.value); }
|
---|
90 | i4_fixed_point operator*=(const i4_fixed_point b)
|
---|
91 | //{{{
|
---|
92 | {
|
---|
93 | return DIRECT_CAST(value = (value*b.value)>>precision);
|
---|
94 | }
|
---|
95 | //}}}
|
---|
96 | i4_fixed_point operator/=(const i4_fixed_point b)
|
---|
97 | //{{{
|
---|
98 | {
|
---|
99 | return DIRECT_CAST(value = (value<<precision) / b.value);
|
---|
100 | }
|
---|
101 | //}}}
|
---|
102 |
|
---|
103 | i4_bool operator==(const i4_fixed_point b) const { return value == b.value; }
|
---|
104 | i4_bool operator!=(const i4_fixed_point b) const { return value != b.value; }
|
---|
105 | i4_bool operator> (const i4_fixed_point b) const { return value > b.value; }
|
---|
106 | i4_bool operator< (const i4_fixed_point b) const { return value < b.value; }
|
---|
107 | i4_bool operator>=(const i4_fixed_point b) const { return value >= b.value; }
|
---|
108 | i4_bool operator<=(const i4_fixed_point b) const { return value <= b.value; }
|
---|
109 |
|
---|
110 | sw32 real() const { return value>>precision; }
|
---|
111 | w32 fraction() const { return w32(value<<(32 - precision)); }
|
---|
112 | w32 precision() const { return precision; }
|
---|
113 | };
|
---|
114 |
|
---|
115 | #endif
|
---|
116 |
|
---|
117 | //{{{ Emacs Locals
|
---|
118 | // Local Variables:
|
---|
119 | // folded-file: t
|
---|
120 | // End:
|
---|
121 | //}}}
|
---|