/[pcsx2_0.9.7]/trunk/common/include/Utilities/FixedPointTypes.h
ViewVC logotype

Contents of /trunk/common/include/Utilities/FixedPointTypes.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 10 months ago) by william
File MIME type: text/plain
File size: 6495 byte(s)
committing r3113 initial commit again...
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #pragma once
17
18 #include "Dependencies.h"
19 #include "Exceptions.h"
20
21 template< int Precision >
22 struct FixedInt
23 {
24 s32 Raw;
25
26 FixedInt()
27 {
28 Raw = 0;
29 }
30
31 FixedInt( int signedval )
32 {
33 Raw = signedval * Precision;
34 }
35
36 FixedInt( double doubval )
37 {
38 Raw = (int)(doubval * (double)Precision);
39 }
40
41 FixedInt( float floval )
42 {
43 Raw = (int)(floval * (float)Precision);
44 }
45
46 bool operator ==( const FixedInt<Precision>& right ) const
47 {
48 return Raw == right.Raw;
49 }
50
51 bool operator !=( const FixedInt<Precision>& right ) const
52 {
53 return Raw != right.Raw;
54 }
55
56 FixedInt<Precision> operator+( const FixedInt<Precision>& right ) const
57 {
58 return FixedInt<Precision>().SetRaw( Raw + right.Raw );
59 }
60
61 FixedInt<Precision> operator-( const FixedInt<Precision>& right ) const
62 {
63 return FixedInt<Precision>().SetRaw( Raw + right.Raw );
64 }
65
66 FixedInt<Precision>& operator+=( const FixedInt<Precision>& right )
67 {
68 return SetRaw( Raw + right.Raw );
69 }
70
71 FixedInt<Precision>& operator-=( const FixedInt<Precision>& right )
72 {
73 return SetRaw( Raw + right.Raw );
74 }
75
76 bool operator>( const FixedInt<Precision>& right ) const { return Raw > right.Raw; }
77 bool operator>=( const FixedInt<Precision>& right ) const { return Raw >= right.Raw; }
78 bool operator<( const FixedInt<Precision>& right ) const { return Raw < right.Raw; }
79 bool operator<=( const FixedInt<Precision>& right ) const { return Raw <= right.Raw; }
80
81 FixedInt<Precision>& ConfineTo( const FixedInt<Precision>& low, const FixedInt<Precision>& high )
82 {
83 return SetRaw( std::min( std::max( Raw, low.Raw ), high.Raw ) );
84 }
85
86 // Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
87 // you'll need to use the Raw values directly.
88 FixedInt<Precision> operator*( const FixedInt<Precision>& right ) const
89 {
90 s64 mulres = (s64)Raw * right.Raw;
91 return FixedInt<Precision>().SetRaw( (s32)(mulres / Precision) );
92 }
93
94 // Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
95 // you'll need to use the Raw values directly.
96 FixedInt<Precision> operator/( const FixedInt<Precision>& right ) const
97 {
98 s64 divres = Raw * Precision;
99 return FixedInt<Precision>().SetRaw( (s32)(divres / right.Raw) );
100 }
101
102 // Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
103 // you'll need to use the Raw values directly.
104 FixedInt<Precision>& operator*=( const FixedInt<Precision>& right )
105 {
106 s64 mulres = (s64)Raw * right.Raw;
107 return SetRaw( (s32)(mulres / Precision) );
108 }
109
110 // Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
111 // you'll need to use the Raw values directly.
112 FixedInt<Precision>& operator/=( const FixedInt<Precision>& right )
113 {
114 s64 divres = Raw * Precision;
115 return SetRaw( (s32)(divres / right.Raw) );
116 }
117
118 // returns TRUE if the value overflows the legal integer range of this container.
119 static bool OverflowCheck( int signedval )
120 {
121 return ( signedval >= (INT_MAX / Precision) );
122 }
123
124 // returns TRUE if the value overflows the legal integer range of this container.
125 static bool OverflowCheck( double signedval )
126 {
127 return ( signedval >= (INT_MAX / Precision) );
128 }
129
130 int GetWhole() const { return Raw / Precision; }
131 int GetFraction() const { return Raw % Precision; }
132
133 FixedInt<Precision>& SetRaw( s32 rawsrc )
134 {
135 Raw = rawsrc;
136 return *this;
137 }
138
139 FixedInt<Precision>& Round()
140 {
141 Raw = ToIntRounded();
142 return *this;
143 }
144
145 FixedInt<Precision>& SetWhole( s32 wholepart )
146 {
147 pxAssert( wholepart < (INT_MAX / Precision) );
148 Raw = GetFraction() + (wholepart * Precision);
149 return *this;
150 }
151
152 FixedInt<Precision>& SetFraction( u32 fracpart )
153 {
154 Raw = (GetWhole() * Precision) + fracpart;
155 return *this;
156 }
157
158 wxString ToString() const
159 {
160 return wxsFormat( L"%d.%d", GetWhole(), (GetFraction() * 100) / Precision );
161 }
162
163 wxString ToString( int fracDigits ) const
164 {
165 if( fracDigits == 0 ) return wxsFormat( L"%d", GetWhole() );
166
167 pxAssert( fracDigits <= 7 ); // higher numbers would just cause overflows and bad mojo.
168 int mulby = (int)pow( 10.0, fracDigits );
169 return wxsFormat( L"%d.%d", GetWhole(), (GetFraction() * mulby) / Precision );
170 }
171
172 double ToDouble() const
173 {
174 return ((double)Raw / (double)Precision);
175 }
176
177 float ToFloat() const
178 {
179 return ((float)Raw / (float)Precision);
180 }
181
182 int ToIntTruncated() const
183 {
184 return Raw / Precision;
185 }
186
187 int ToIntRounded() const
188 {
189 return (Raw + (Precision/2)) / Precision;
190 }
191
192 static bool TryFromString( FixedInt<Precision>& dest, const wxString& parseFrom )
193 {
194 long whole=0, frac=0;
195 const wxString beforeFirst( parseFrom.BeforeFirst( L'.' ) );
196 const wxString afterFirst( parseFrom.AfterFirst( L'.' ).Mid(0, 5) );
197 bool success = true;
198
199 if( !beforeFirst.IsEmpty() )
200 success = success && beforeFirst.ToLong( &whole );
201
202 if( !afterFirst.IsEmpty() )
203 success = success && afterFirst.ToLong( &frac );
204
205 if( !success ) return false;
206
207 dest.SetWhole( whole );
208
209 if( afterFirst.Length() != 0 && frac != 0 )
210 {
211 int fracPower = (int)pow( 10.0, (int)afterFirst.Length() );
212 dest.SetFraction( (frac * Precision) / fracPower );
213 }
214 return true;
215 }
216
217 static FixedInt<Precision> FromString( const wxString& parseFrom, const FixedInt<Precision>& defval )
218 {
219 FixedInt<Precision> dest;
220 if( !TryFromString( dest, parseFrom ) ) return defval;
221 return dest;
222 }
223
224 // This version of FromString throws a ParseError exception if the conversion fails.
225 static FixedInt<Precision> FromString( const wxString parseFrom )
226 {
227 FixedInt<Precision> dest;
228 if( !TryFromString( dest, parseFrom ) ) throw Exception::ParseError(
229 wxsFormat(L"Parse error on FixedInt<%d>::FromString", Precision), wxEmptyString
230 );
231 return dest;
232 }
233 };
234
235 typedef FixedInt<256> Fixed256;
236 typedef FixedInt<100> Fixed100;

  ViewVC Help
Powered by ViewVC 1.1.22