A fixed point library from Trenki http://www.trenki.net/content/view/17/1/ Slightly modified so that the fixed point data structure can automatically cast itself to float or int when used in an expression.

Committer:
sravet
Date:
Wed Oct 20 02:20:46 2010 +0000
Revision:
0:aa2871c4c041
First checkin.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sravet 0:aa2871c4c041 1 /*
sravet 0:aa2871c4c041 2 Copyright (c) 2007, Markus Trenkwalder
sravet 0:aa2871c4c041 3
sravet 0:aa2871c4c041 4 All rights reserved.
sravet 0:aa2871c4c041 5
sravet 0:aa2871c4c041 6 Redistribution and use in source and binary forms, with or without
sravet 0:aa2871c4c041 7 modification, are permitted provided that the following conditions are met:
sravet 0:aa2871c4c041 8
sravet 0:aa2871c4c041 9 * Redistributions of source code must retain the above copyright notice,
sravet 0:aa2871c4c041 10 this list of conditions and the following disclaimer.
sravet 0:aa2871c4c041 11
sravet 0:aa2871c4c041 12 * Redistributions in binary form must reproduce the above copyright notice,
sravet 0:aa2871c4c041 13 this list of conditions and the following disclaimer in the documentation
sravet 0:aa2871c4c041 14 and/or other materials provided with the distribution.
sravet 0:aa2871c4c041 15
sravet 0:aa2871c4c041 16 * Neither the name of the library's copyright owner nor the names of its
sravet 0:aa2871c4c041 17 contributors may be used to endorse or promote products derived from this
sravet 0:aa2871c4c041 18 software without specific prior written permission.
sravet 0:aa2871c4c041 19
sravet 0:aa2871c4c041 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
sravet 0:aa2871c4c041 21 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
sravet 0:aa2871c4c041 22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
sravet 0:aa2871c4c041 23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
sravet 0:aa2871c4c041 24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
sravet 0:aa2871c4c041 25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
sravet 0:aa2871c4c041 26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
sravet 0:aa2871c4c041 27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
sravet 0:aa2871c4c041 28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
sravet 0:aa2871c4c041 29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
sravet 0:aa2871c4c041 30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
sravet 0:aa2871c4c041 31 */
sravet 0:aa2871c4c041 32
sravet 0:aa2871c4c041 33 #ifndef FIXEDP_CLASS_H_INCLUDED
sravet 0:aa2871c4c041 34 #define FIXEDP_CLASS_H_INCLUDED
sravet 0:aa2871c4c041 35
sravet 0:aa2871c4c041 36 #ifdef _MSC_VER
sravet 0:aa2871c4c041 37 #pragma once
sravet 0:aa2871c4c041 38 #endif
sravet 0:aa2871c4c041 39
sravet 0:aa2871c4c041 40 #include "fixed_func.h"
sravet 0:aa2871c4c041 41
sravet 0:aa2871c4c041 42 namespace fixedpoint {
sravet 0:aa2871c4c041 43
sravet 0:aa2871c4c041 44 // The template argument p in all of the following functions refers to the
sravet 0:aa2871c4c041 45 // fixed point precision (e.g. p = 8 gives 24.8 fixed point functions).
sravet 0:aa2871c4c041 46
sravet 0:aa2871c4c041 47 template <int p>
sravet 0:aa2871c4c041 48 struct fixed_point {
sravet 0:aa2871c4c041 49 int32_t intValue;
sravet 0:aa2871c4c041 50
sravet 0:aa2871c4c041 51 fixed_point() {}
sravet 0:aa2871c4c041 52 /*explicit*/ fixed_point(int32_t i) : intValue(i << p) {}
sravet 0:aa2871c4c041 53 /*explicit*/ fixed_point(float f) : intValue(float2fix<p>(f)) {}
sravet 0:aa2871c4c041 54 /*explicit*/ fixed_point(double f) : intValue(float2fix<p>((float)f)) {}
sravet 0:aa2871c4c041 55
sravet 0:aa2871c4c041 56 fixed_point& operator += (fixed_point r) { intValue += r.intValue; return *this; }
sravet 0:aa2871c4c041 57 fixed_point& operator -= (fixed_point r) { intValue -= r.intValue; return *this; }
sravet 0:aa2871c4c041 58 fixed_point& operator *= (fixed_point r) { intValue = fixmul<p>(intValue, r.intValue); return *this; }
sravet 0:aa2871c4c041 59 fixed_point& operator /= (fixed_point r) { intValue = fixdiv<p>(intValue, r.intValue); return *this; }
sravet 0:aa2871c4c041 60
sravet 0:aa2871c4c041 61 fixed_point& operator *= (int32_t r) { intValue *= r; return *this; }
sravet 0:aa2871c4c041 62 fixed_point& operator /= (int32_t r) { intValue /= r; return *this; }
sravet 0:aa2871c4c041 63
sravet 0:aa2871c4c041 64 fixed_point operator - () const { fixed_point x; x.intValue = -intValue; return x; }
sravet 0:aa2871c4c041 65 fixed_point operator + (fixed_point r) const { fixed_point x = *this; x += r; return x;}
sravet 0:aa2871c4c041 66 fixed_point operator - (fixed_point r) const { fixed_point x = *this; x -= r; return x;}
sravet 0:aa2871c4c041 67 fixed_point operator * (fixed_point r) const { fixed_point x = *this; x *= r; return x;}
sravet 0:aa2871c4c041 68 fixed_point operator / (fixed_point r) const { fixed_point x = *this; x /= r; return x;}
sravet 0:aa2871c4c041 69
sravet 0:aa2871c4c041 70 bool operator == (fixed_point r) const { return intValue == r.intValue; }
sravet 0:aa2871c4c041 71 bool operator != (fixed_point r) const { return !(*this == r); }
sravet 0:aa2871c4c041 72 bool operator < (fixed_point r) const { return intValue < r.intValue; }
sravet 0:aa2871c4c041 73 bool operator > (fixed_point r) const { return intValue > r.intValue; }
sravet 0:aa2871c4c041 74 bool operator <= (fixed_point r) const { return intValue <= r.intValue; }
sravet 0:aa2871c4c041 75 bool operator >= (fixed_point r) const { return intValue >= r.intValue; }
sravet 0:aa2871c4c041 76
sravet 0:aa2871c4c041 77 fixed_point operator + (int32_t r) const { fixed_point x = *this; x += r; return x;}
sravet 0:aa2871c4c041 78 fixed_point operator - (int32_t r) const { fixed_point x = *this; x -= r; return x;}
sravet 0:aa2871c4c041 79 fixed_point operator * (int32_t r) const { fixed_point x = *this; x *= r; return x;}
sravet 0:aa2871c4c041 80 fixed_point operator / (int32_t r) const { fixed_point x = *this; x /= r; return x;}
sravet 0:aa2871c4c041 81 operator int() const { return intValue>>p; }
sravet 0:aa2871c4c041 82 operator float() const { return fix2float<p>(intValue); }
sravet 0:aa2871c4c041 83 };
sravet 0:aa2871c4c041 84
sravet 0:aa2871c4c041 85 // Specializations for use with plain integers
sravet 0:aa2871c4c041 86 template <int p>
sravet 0:aa2871c4c041 87 inline fixed_point<p> operator + (int32_t a, fixed_point<p> b)
sravet 0:aa2871c4c041 88 { return b + a; }
sravet 0:aa2871c4c041 89
sravet 0:aa2871c4c041 90 template <int p>
sravet 0:aa2871c4c041 91 inline fixed_point<p> operator - (int32_t a, fixed_point<p> b)
sravet 0:aa2871c4c041 92 { return -b + a; }
sravet 0:aa2871c4c041 93
sravet 0:aa2871c4c041 94 template <int p>
sravet 0:aa2871c4c041 95 inline fixed_point<p> operator * (int32_t a, fixed_point<p> b)
sravet 0:aa2871c4c041 96 { return b * a; }
sravet 0:aa2871c4c041 97
sravet 0:aa2871c4c041 98 template <int p>
sravet 0:aa2871c4c041 99 inline fixed_point<p> operator / (int32_t a, fixed_point<p> b)
sravet 0:aa2871c4c041 100 { fixed_point<p> r(a); r /= b; return r; }
sravet 0:aa2871c4c041 101
sravet 0:aa2871c4c041 102 // math functions
sravet 0:aa2871c4c041 103 // no default implementation
sravet 0:aa2871c4c041 104
sravet 0:aa2871c4c041 105 template <int p>
sravet 0:aa2871c4c041 106 inline fixed_point<p> sin(fixed_point<p> a);
sravet 0:aa2871c4c041 107
sravet 0:aa2871c4c041 108 template <int p>
sravet 0:aa2871c4c041 109 inline fixed_point<p> cos(fixed_point<p> a);
sravet 0:aa2871c4c041 110
sravet 0:aa2871c4c041 111 template <int p>
sravet 0:aa2871c4c041 112 inline fixed_point<p> sqrt(fixed_point<p> a);
sravet 0:aa2871c4c041 113
sravet 0:aa2871c4c041 114 template <int p>
sravet 0:aa2871c4c041 115 inline fixed_point<p> rsqrt(fixed_point<p> a);
sravet 0:aa2871c4c041 116
sravet 0:aa2871c4c041 117 template <int p>
sravet 0:aa2871c4c041 118 inline fixed_point<p> inv(fixed_point<p> a);
sravet 0:aa2871c4c041 119
sravet 0:aa2871c4c041 120 template <int p>
sravet 0:aa2871c4c041 121 inline fixed_point<p> abs(fixed_point<p> a)
sravet 0:aa2871c4c041 122 {
sravet 0:aa2871c4c041 123 fixed_point<p> r;
sravet 0:aa2871c4c041 124 r.intValue = a.intValue > 0 ? a.intValue : -a.intValue;
sravet 0:aa2871c4c041 125 return r;
sravet 0:aa2871c4c041 126 }
sravet 0:aa2871c4c041 127
sravet 0:aa2871c4c041 128 // specializations for 16.16 format
sravet 0:aa2871c4c041 129
sravet 0:aa2871c4c041 130 template <>
sravet 0:aa2871c4c041 131 inline fixed_point<16> sin(fixed_point<16> a)
sravet 0:aa2871c4c041 132 {
sravet 0:aa2871c4c041 133 fixed_point<16> r;
sravet 0:aa2871c4c041 134 r.intValue = fixsin16(a.intValue);
sravet 0:aa2871c4c041 135 return r;
sravet 0:aa2871c4c041 136 }
sravet 0:aa2871c4c041 137
sravet 0:aa2871c4c041 138 template <>
sravet 0:aa2871c4c041 139 inline fixed_point<16> cos(fixed_point<16> a)
sravet 0:aa2871c4c041 140 {
sravet 0:aa2871c4c041 141 fixed_point<16> r;
sravet 0:aa2871c4c041 142 r.intValue = fixcos16(a.intValue);
sravet 0:aa2871c4c041 143 return r;
sravet 0:aa2871c4c041 144 }
sravet 0:aa2871c4c041 145
sravet 0:aa2871c4c041 146
sravet 0:aa2871c4c041 147 template <>
sravet 0:aa2871c4c041 148 inline fixed_point<16> sqrt(fixed_point<16> a)
sravet 0:aa2871c4c041 149 {
sravet 0:aa2871c4c041 150 fixed_point<16> r;
sravet 0:aa2871c4c041 151 r.intValue = fixsqrt16(a.intValue);
sravet 0:aa2871c4c041 152 return r;
sravet 0:aa2871c4c041 153 }
sravet 0:aa2871c4c041 154
sravet 0:aa2871c4c041 155 template <>
sravet 0:aa2871c4c041 156 inline fixed_point<16> rsqrt(fixed_point<16> a)
sravet 0:aa2871c4c041 157 {
sravet 0:aa2871c4c041 158 fixed_point<16> r;
sravet 0:aa2871c4c041 159 r.intValue = fixrsqrt16(a.intValue);
sravet 0:aa2871c4c041 160 return r;
sravet 0:aa2871c4c041 161 }
sravet 0:aa2871c4c041 162
sravet 0:aa2871c4c041 163 template <>
sravet 0:aa2871c4c041 164 inline fixed_point<16> inv(fixed_point<16> a)
sravet 0:aa2871c4c041 165 {
sravet 0:aa2871c4c041 166 fixed_point<16> r;
sravet 0:aa2871c4c041 167 r.intValue = fixinv<16>(a.intValue);
sravet 0:aa2871c4c041 168 return r;
sravet 0:aa2871c4c041 169 }
sravet 0:aa2871c4c041 170
sravet 0:aa2871c4c041 171 // The multiply accumulate case can be optimized.
sravet 0:aa2871c4c041 172 template <int p>
sravet 0:aa2871c4c041 173 inline fixed_point<p> multiply_accumulate(
sravet 0:aa2871c4c041 174 int count,
sravet 0:aa2871c4c041 175 const fixed_point<p> *a,
sravet 0:aa2871c4c041 176 const fixed_point<p> *b)
sravet 0:aa2871c4c041 177 {
sravet 0:aa2871c4c041 178 long long result = 0;
sravet 0:aa2871c4c041 179 for (int i = 0; i < count; ++i)
sravet 0:aa2871c4c041 180 result += static_cast<long long>(a[i].intValue) * b[i].intValue;
sravet 0:aa2871c4c041 181 fixed_point<p> r;
sravet 0:aa2871c4c041 182 r.intValue = static_cast<int>(result >> p);
sravet 0:aa2871c4c041 183 return r;
sravet 0:aa2871c4c041 184 }
sravet 0:aa2871c4c041 185
sravet 0:aa2871c4c041 186 } // end namespace fixedpoint
sravet 0:aa2871c4c041 187
sravet 0:aa2871c4c041 188 #endif
sravet 0:aa2871c4c041 189