blob: aa292f0f54d951c10e66588331803d3fee8702c6 [file] [log] [blame]
dburgess82c46ff2011-10-07 02:40:51 +00001/*
2* Copyright 2009 Free Software Foundation, Inc.
3*
4* This software is distributed under the terms of the GNU Affero Public License.
5* See the COPYING file in the main directory for details.
6*
7* This use of this software may be subject to additional restrictions.
8* See the LEGAL file in the main directory for details.
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU Affero General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Affero General Public License for more details.
19
20 You should have received a copy of the GNU Affero General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22
23*/
24
25
26#ifndef F16_H
27#define F16_H
28
29#include <stdint.h>
30#include <ostream>
31
32
33
34/** Round a float to the appropriate F16 value. */
35inline int32_t _f16_round(float f)
36{
37 if (f>0.0F) return (int32_t)(f+0.5F);
38 if (f<0.0F) return (int32_t)(f-0.5F);
39 return 0;
40}
41
42
43
44/** A class for F15.16 fixed point arithmetic with saturation. */
45class F16 {
46
47
48 private:
49
50 int32_t mV;
51
52
53 public:
54
55 F16() {}
56
57 F16(int i) { mV = i<<16; }
58 F16(float f) { mV = _f16_round(f*65536.0F); }
59 F16(double f) { mV = _f16_round((float)f*65536.0F); }
60
61 int32_t& raw() { return mV; }
62 const int32_t& raw() const { return mV; }
63
64 float f() const { return mV/65536.0F; }
65
66 //operator float() const { return mV/65536.0F; }
67 //operator int() const { return mV>>16; }
68
69 F16 operator=(float f)
70 {
71 mV = _f16_round(f*65536.0F);
72 return *this;
73 }
74
75 F16 operator=(int i)
76 {
77 mV = i<<16;
78 return *this;
79 }
80
81 F16 operator=(const F16& other)
82 {
83 mV = other.mV;
84 return mV;
85 }
86
87 F16 operator+(const F16& other) const
88 {
89 F16 retVal;
90 retVal.mV = mV + other.mV;
91 return retVal;
92 }
93
94 F16& operator+=(const F16& other)
95 {
96 mV += other.mV;
97 return *this;
98 }
99
100 F16 operator-(const F16& other) const
101 {
102 F16 retVal;
103 retVal.mV = mV - other.mV;
104 return retVal;
105 }
106
107 F16& operator-=(const F16& other)
108 {
109 mV -= other.mV;
110 return *this;
111 }
112
113 F16 operator*(const F16& other) const
114 {
115 F16 retVal;
116 int64_t p = (int64_t)mV * (int64_t)other.mV;
117 retVal.mV = p>>16;
118 return retVal;
119 }
120
121 F16& operator*=(const F16& other)
122 {
123 int64_t p = (int64_t)mV * (int64_t)other.mV;
124 mV = p>>16;
125 return *this;
126 }
127
128 F16 operator*(float f) const
129 {
130 F16 retVal;
131 retVal.mV = mV * f;
132 return retVal;
133 }
134
135 F16& operator*=(float f)
136 {
137 mV *= f;
138 return *this;
139 }
140
141 F16 operator/(const F16& other) const
142 {
143 F16 retVal;
144 int64_t pV = (int64_t)mV << 16;
145 retVal.mV = pV / other.mV;
146 return retVal;
147 }
148
149 F16& operator/=(const F16& other)
150 {
151 int64_t pV = (int64_t)mV << 16;
152 mV = pV / other.mV;
153 return *this;
154 }
155
156 F16 operator/(float f) const
157 {
158 F16 retVal;
159 retVal.mV = mV / f;
160 return retVal;
161 }
162
163 F16& operator/=(float f)
164 {
165 mV /= f;
166 return *this;
167 }
168
169 bool operator>(const F16& other) const
170 {
171 return mV>other.mV;
172 }
173
174 bool operator<(const F16& other) const
175 {
176 return mV<other.mV;
177 }
178
179 bool operator==(const F16& other) const
180 {
181 return mV==other.mV;
182 }
183
184 bool operator>(float f) const
185 {
186 return (mV/65536.0F) > f;
187 }
188
189 bool operator<(float f) const
190 {
191 return (mV/65536.0F) < f;
192 }
193
194 bool operator==(float f) const
195 {
196 return (mV/65536.0F) == f;
197 }
198
199};
200
201
202
203inline std::ostream& operator<<(std::ostream& os, const F16& v)
204{
205 os << v.f();
206 return os;
207}
208
209#endif
210