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, and added the functionality to cast between precisions.

Committer:
madcowswe
Date:
Sun Nov 27 00:28:31 2011 +0000
Revision:
0:ca79fb4a8165
Child:
1:ac99b6f474a0
added the functionality to cast between precisions

Who changed what in which revision?

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