Skip to content

Commit b8d910b

Browse files
author
Geoffrey Hunter
committed
Added conversion methods, casting capabilities and associated unit tests for the class.
1 parent 8cda7f9 commit b8d910b

File tree

5 files changed

+166
-50
lines changed

5 files changed

+166
-50
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
88

99
### Added
1010
- Added compile time check to `FpF` class to make sure template parameters are the same before doing multiplication.
11+
- Added README code to a new example folder (to make sure it compiles correctly).
12+
- Added conversion methods, casting capabilities and associated unit tests for the `FpF` class.
1113

1214
### Fixed
1315
- Removed reference to non-existant MFixedPoint library when linking the benchmark and unit test code.

include/MFixedPoint/FpF.hpp

Lines changed: 75 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ inline int32_t fixinv(int32_t a)
139139

140140
/// \brief Converts from float to a raw 32-bit fixed-point number.
141141
/// \details Do not write "myFpNum = FloatToRawFix32()"! This function outputs a raw
142-
/// number, so you would have to use the syntax "myFpNum.rawVal = FloatToRawFix32()".
142+
/// number, so you would have to use the syntax "myFpNum.rawVal_ = FloatToRawFix32()".
143143
/// \warning Slow!
144144
template <uint8_t q>
145145
int32_t FloatToRawFix32(float f) {
@@ -148,7 +148,7 @@ int32_t FloatToRawFix32(float f) {
148148

149149
/// \brief Converts from double to a raw 32-bit fixed-point number.
150150
/// \details Do not write "myFpNum = DoubleToRawFix32()"! This function outputs a raw
151-
/// number, so you would have to use the syntax "myFpNum.rawVal = DoubleToRawFix32()".
151+
/// number, so you would have to use the syntax "myFpNum.rawVal_ = DoubleToRawFix32()".
152152
/// \warning Slow!
153153
template <uint8_t q>
154154
int32_t DoubleToRawFix32(double f) {
@@ -172,74 +172,84 @@ template <class BaseType, class OverflowType, uint8_t numFracBits>
172172
class FpF {
173173

174174
public:
175-
176-
/// \brief The fixed-point number is stored in this basic data type.
177-
BaseType rawVal;
175+
176+
//===============================================================================================//
177+
//================================== CONSTRUCTORS/DESTRUCTORS ===================================//
178+
//===============================================================================================//
178179

179180
FpF()
180181
{
181182
#if(fpConfig_PRINT_DEBUG_GENERAL == 1)
182183
//Port::DebugPrint("FP: New fixed-point object created.");
183184
#endif
184185
}
186+
187+
//===============================================================================================//
188+
//========================================= GETTERS/SETTERS =====================================//
189+
//===============================================================================================//
190+
191+
/// \brief Get the raw value (memory representation) of this fixed-point number,
192+
BaseType GetRawVal() const {
193+
return rawVal_;
194+
}
185195

186196
FpF(int8_t i) :
187-
rawVal((int32_t)i << numFracBits) {}
197+
rawVal_((int32_t)i << numFracBits) {}
188198

189199
FpF(int16_t i) :
190-
rawVal((int32_t)i << numFracBits) {}
200+
rawVal_((int32_t)i << numFracBits) {}
191201

192202
FpF(int32_t i) :
193-
rawVal(i << numFracBits) { }
203+
rawVal_(i << numFracBits) { }
194204

195205
/// \brief Constructor that accepts a float.
196206
FpF(float f) :
197-
rawVal((BaseType)(f * (float)(1 << numFracBits))) {}
207+
rawVal_((BaseType)(f * (float)(1 << numFracBits))) {}
198208

199209

200210
FpF(double f) :
201-
rawVal((BaseType)(f * (double)(1 << numFracBits))) {}
211+
rawVal_((BaseType)(f * (double)(1 << numFracBits))) {}
202212

203213
// Compound Arithmetic Overloads
204214

205215
FpF& operator += (FpF r) {
206-
rawVal += r.rawVal;
216+
rawVal_ += r.rawVal_;
207217
return *this;
208218
}
209219

210220
FpF& operator -= (FpF r) {
211-
rawVal -= r.rawVal;
221+
rawVal_ -= r.rawVal_;
212222
return *this;
213223
}
214224

215225
/// \brief Overlaod for '*=' operator.
216226
/// \details Uses intermediatary casting to int64_t to prevent overflows.
217227
FpF& operator *= (FpF r) {
218-
rawVal = FpFMultiply<BaseType, OverflowType, numFracBits>(rawVal, r.rawVal);
228+
rawVal_ = FpFMultiply<BaseType, OverflowType, numFracBits>(rawVal_, r.rawVal_);
219229
return *this;
220230
}
221231

222232
/// \brief Overlaod for '/=' operator.
223233
/// \details Uses intermediatary casting to int64_t to prevent overflows.
224234
FpF& operator /= (FpF r) {
225-
rawVal = fixdiv<numFracBits>(rawVal, r.rawVal);
235+
rawVal_ = fixdiv<numFracBits>(rawVal_, r.rawVal_);
226236
return *this;
227237
}
228238

229239
/// \brief Overlaod for '%=' operator.
230240
FpF& operator %= (FpF r) {
231-
rawVal %= r.rawVal;
241+
rawVal_ %= r.rawVal_;
232242
return *this;
233243
}
234244

235245

236246
FpF& operator *= (int32_t r) {
237-
rawVal *= r;
247+
rawVal_ *= r;
238248
return *this;
239249
}
240250

241251
FpF& operator /= (int32_t r) {
242-
rawVal /= r;
252+
rawVal_ /= r;
243253
return *this;
244254
}
245255

@@ -248,7 +258,7 @@ class FpF {
248258
/// \brief Overload for '-itself' operator.
249259
FpF operator - () const {
250260
FpF x;
251-
x.rawVal = -rawVal;
261+
x.rawVal_ = -rawVal_;
252262
return x;
253263
}
254264

@@ -304,7 +314,7 @@ class FpF {
304314

305315
bool operator == (FpF r) const
306316
{
307-
return rawVal == r.rawVal;
317+
return rawVal_ == r.rawVal_;
308318
}
309319

310320
bool operator != (const FpF &r)
@@ -314,61 +324,77 @@ class FpF {
314324

315325
bool operator < (const FpF &r)
316326
{
317-
return rawVal < r.rawVal;
327+
return rawVal_ < r.rawVal_;
318328
}
319329

320330
bool operator > (const FpF &r)
321331
{
322-
return rawVal > r.rawVal;
332+
return rawVal_ > r.rawVal_;
323333
}
324334

325335
bool operator <= (FpF r) const
326336
{
327-
return rawVal <= r.rawVal;
337+
return rawVal_ <= r.rawVal_;
328338
}
329339

330340
bool operator >= (FpF r) const
331341
{
332-
return rawVal >= r.rawVal;
342+
return rawVal_ >= r.rawVal_;
333343
}
334344

335345
/// \defgroup From FpF Conversion Overloads (casts)
336346
/// \{
337-
347+
348+
349+
/// \brief Converts the fixed-point number into an integer.
350+
/// \details Always rounds to negative infinity (66.3 becomes 66, -66.3 becomes -67).
351+
/// \tparam IntType The return integer type.
352+
template <class IntType>
353+
IntType ToInt() const {
354+
// Right-shift to get rid of all the decimal bits
355+
// This rounds towards negative infinity
356+
return (IntType)(rawVal_ >> numFracBits);
357+
}
358+
359+
/// \brief Converts the fixed-point number to a float.
360+
float ToFloat() const {
361+
return (float)rawVal_ / (float)(1 << numFracBits);
362+
}
363+
338364
/// \brief Converts the fixed-point number to a double.
339365
double ToDouble() const {
340-
return (double)rawVal / (double)(1 << numFracBits);
366+
return (double)rawVal_ / (double)(1 << numFracBits);
341367
}
342368

343369
/// \brief Conversion operator from fixed-point to int16_t.
344370
/// \warning Possible loss of accuracy from conversion from
345371
/// int32_t to int16_t.
346372
operator int16_t() {
347373
// Right-shift to get rid of all the decimal bits (truncate)
348-
return (int16_t)(rawVal >> numFracBits);
374+
return (int16_t)(rawVal_ >> numFracBits);
349375
}
350376

351377
/// \brief Conversion operator from fixed-point to int32_t.
352378
operator int32_t() {
353379
// Right-shift to get rid of all the decimal bits (truncate)
354-
return (rawVal >> numFracBits);
380+
return (rawVal_ >> numFracBits);
355381
}
356382

357383
/// \brief Conversion operator from fixed-point to int64_t.
358384
operator int64_t() {
359385
// Right-shift to get rid of all the decimal bits (truncate)
360-
return (int64_t)(rawVal >> numFracBits);
386+
return (int64_t)(rawVal_ >> numFracBits);
361387
}
362388

363389
/// \brief Conversion operator from fixed-point to float.
364390
operator float() {
365-
return (float)rawVal / (float)(1 << numFracBits);
391+
return (float)rawVal_ / (float)(1 << numFracBits);
366392
}
367393

368394
/// \brief Conversion operator from fixed-point to double.
369395
/// \note Similar to float conversion.
370396
operator double() {
371-
return (double)rawVal / (double)(1 << numFracBits);
397+
return (double)rawVal_ / (double)(1 << numFracBits);
372398
}
373399

374400
/// \}
@@ -402,30 +428,35 @@ class FpF {
402428
}
403429

404430
bool operator > (int32_t r) const {
405-
return rawVal > (r << numFracBits);
431+
return rawVal_ > (r << numFracBits);
406432
}
407433

408434
bool operator >= (int32_t r) const {
409-
return rawVal >= (r << numFracBits);
435+
return rawVal_ >= (r << numFracBits);
410436
}
411437

412438
bool operator < (int32_t r) const {
413-
return rawVal < (r << numFracBits);
439+
return rawVal_ < (r << numFracBits);
414440
}
415441

416442
bool operator <= (int32_t r) const {
417-
return rawVal < (r << numFracBits);
443+
return rawVal_ < (r << numFracBits);
418444
}
419445

420446
bool operator == (int32_t r) const {
421-
return rawVal == (r << numFracBits);
447+
return rawVal_ == (r << numFracBits);
422448
}
423449

424450
bool operator != (int32_t r) const {
425-
return rawVal != (r << numFracBits);
451+
return rawVal_ != (r << numFracBits);
426452
}
427453

428454
/// \}
455+
456+
private:
457+
458+
/// \brief The fixed-point number is stored in this basic data type.
459+
BaseType rawVal_;
429460

430461
};
431462

@@ -492,7 +523,7 @@ using FpF64 = FpF<int64_t, int64_t, numFracBits>;
492523
// inline FpF<numFracBits> abs(FpF<numFracBits> a)
493524
// {
494525
// FpF<numFracBits> r;
495-
// r.rawVal = a.rawVal > 0 ? a.rawVal : -a.rawVal;
526+
// r.rawVal_ = a.rawVal_ > 0 ? a.rawVal_ : -a.rawVal_;
496527
// return r;
497528
// }
498529

@@ -502,15 +533,15 @@ using FpF64 = FpF<int64_t, int64_t, numFracBits>;
502533
// inline FpF<16> sin(FpF<16> a)
503534
// {
504535
// FpF<16> r;
505-
// r.rawVal = fixsin16(a.rawVal);
536+
// r.rawVal_ = fixsin16(a.rawVal_);
506537
// return r;
507538
// }
508539

509540
// template <>
510541
// inline FpF<16> cos(FpF<16> a)
511542
// {
512543
// FpF<16> r;
513-
// r.rawVal = fixcos16(a.rawVal);
544+
// r.rawVal_ = fixcos16(a.rawVal_);
514545
// return r;
515546
// }
516547

@@ -519,23 +550,23 @@ using FpF64 = FpF<int64_t, int64_t, numFracBits>;
519550
// inline FpF<16> sqrt(FpF<16> a)
520551
// {
521552
// FpF<16> r;
522-
// r.rawVal = fixsqrt16(a.rawVal);
553+
// r.rawVal_ = fixsqrt16(a.rawVal_);
523554
// return r;
524555
// }
525556

526557
// template <>
527558
// inline FpF<16> rsqrt(FpF<16> a)
528559
// {
529560
// FpF<16> r;
530-
// r.rawVal = fixrsqrt16(a.rawVal);
561+
// r.rawVal_ = fixrsqrt16(a.rawVal_);
531562
// return r;
532563
// }
533564

534565
// template <>
535566
// inline FpF<16> inv(FpF<16> a)
536567
// {
537568
// FpF<16> r;
538-
// r.rawVal = fixinv<16>(a.rawVal);
569+
// r.rawVal_ = fixinv<16>(a.rawVal_);
539570
// return r;
540571
// }
541572

@@ -548,9 +579,9 @@ using FpF64 = FpF<int64_t, int64_t, numFracBits>;
548579
// {
549580
// long long result = 0;
550581
// for (int32_t i = 0; i < count; ++i)
551-
// result += static_cast<long long>(a[i].rawVal) * b[i].rawVal;
582+
// result += static_cast<long long>(a[i].rawVal_) * b[i].rawVal_;
552583
// FpF<numFracBits> r;
553-
// r.rawVal = static_cast<int32_t>(result >> numFracBits);
584+
// r.rawVal_ = static_cast<int32_t>(result >> numFracBits);
554585
// return r;
555586
// }
556587

include/MFixedPoint/FpS.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ class FpS {
396396
/// constructor).
397397
uint8_t numFracBits_;
398398

399-
};
399+
}; // class FpS
400400

401401
//===============================================================================================//
402402
//========================================= SPECIALIZATIONS =====================================//

0 commit comments

Comments
 (0)