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.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fixed_class.h Source File

fixed_class.h

00001 /*
00002 Copyright (c) 2007, Markus Trenkwalder
00003 
00004 All rights reserved.
00005 
00006 Redistribution and use in source and binary forms, with or without 
00007 modification, are permitted provided that the following conditions are met:
00008 
00009 * Redistributions of source code must retain the above copyright notice, 
00010   this list of conditions and the following disclaimer.
00011 
00012 * Redistributions in binary form must reproduce the above copyright notice,
00013   this list of conditions and the following disclaimer in the documentation 
00014   and/or other materials provided with the distribution.
00015 
00016 * Neither the name of the library's copyright owner nor the names of its 
00017   contributors may be used to endorse or promote products derived from this 
00018   software without specific prior written permission.
00019 
00020 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00023 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00024 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031 */
00032 
00033 #ifndef FIXEDP_CLASS_H_INCLUDED
00034 #define FIXEDP_CLASS_H_INCLUDED
00035 
00036 #ifdef _MSC_VER
00037 #pragma once
00038 #endif
00039 
00040 #include "fixed_func.h"
00041 
00042 namespace fixedpoint {
00043 
00044 // The template argument p in all of the following functions refers to the 
00045 // fixed point precision (e.g. p = 8 gives 24.8 fixed point functions).
00046 
00047 template <int p>
00048 struct fixed_point {
00049     int32_t intValue;
00050     
00051     fixed_point() {}
00052     /*explicit*/ fixed_point(int32_t i) : intValue(i << p) {}
00053     /*explicit*/ fixed_point(float f) : intValue(float2fix<p>(f)) {}
00054     /*explicit*/ fixed_point(double f) : intValue(float2fix<p>((float)f)) {}
00055     
00056     fixed_point& operator += (fixed_point r) { intValue += r.intValue; return *this; }
00057     fixed_point& operator -= (fixed_point r) { intValue -= r.intValue; return *this; }
00058     fixed_point& operator *= (fixed_point r) { intValue = fixmul<p>(intValue, r.intValue); return *this; }
00059     fixed_point& operator /= (fixed_point r) { intValue = fixdiv<p>(intValue, r.intValue); return *this; }
00060     
00061     fixed_point& operator *= (int32_t r) { intValue *= r; return *this; }
00062     fixed_point& operator /= (int32_t r) { intValue /= r; return *this; }
00063     
00064     fixed_point operator - () const { fixed_point x; x.intValue = -intValue; return x; }
00065     fixed_point operator + (fixed_point r) const { fixed_point x = *this; x += r; return x;}
00066     fixed_point operator - (fixed_point r) const { fixed_point x = *this; x -= r; return x;}
00067     fixed_point operator * (fixed_point r) const { fixed_point x = *this; x *= r; return x;}
00068     fixed_point operator / (fixed_point r) const { fixed_point x = *this; x /= r; return x;}
00069     
00070     bool operator == (fixed_point r) const { return intValue == r.intValue; }
00071     bool operator != (fixed_point r) const { return !(*this == r); }
00072     bool operator <  (fixed_point r) const { return intValue < r.intValue; }
00073     bool operator >  (fixed_point r) const { return intValue > r.intValue; }
00074     bool operator <= (fixed_point r) const { return intValue <= r.intValue; }
00075     bool operator >= (fixed_point r) const { return intValue >= r.intValue; }
00076 
00077     fixed_point operator + (int32_t r) const { fixed_point x = *this; x += r; return x;}
00078     fixed_point operator - (int32_t r) const { fixed_point x = *this; x -= r; return x;}
00079     fixed_point operator * (int32_t r) const { fixed_point x = *this; x *= r; return x;}
00080     fixed_point operator / (int32_t r) const { fixed_point x = *this; x /= r; return x;}
00081     operator int()         const { return intValue>>p; }
00082     operator float()       const { return fix2float<p>(intValue); }
00083     operator double()       const { return (double)intValue / (1 << p); }
00084     
00085     //Added casting and constructing from another precision
00086     template <int q>
00087     fixed_point(const fixed_point<q> &r) : intValue(q <= p ? r.intValue << (p - q) : r.intValue >> (q - p)) {}
00088 };
00089 
00090 // Specializations for use with plain integers
00091 template <int p>
00092 inline fixed_point<p> operator + (int32_t a, fixed_point<p> b)
00093 { return b + a; }
00094 
00095 template <int p>
00096 inline fixed_point<p> operator - (int32_t a, fixed_point<p> b)
00097 { return -b + a; }
00098 
00099 template <int p>
00100 inline fixed_point<p> operator * (int32_t a, fixed_point<p> b)
00101 { return b * a; }
00102 
00103 template <int p>
00104 inline fixed_point<p> operator / (int32_t a, fixed_point<p> b)
00105 { fixed_point<p> r(a); r /= b; return r; }
00106 
00107 // math functions
00108 // no default implementation
00109 
00110 template <int p>
00111 inline fixed_point<p> sin(fixed_point<p> a);
00112 
00113 template <int p>
00114 inline fixed_point<p> cos(fixed_point<p> a);
00115 
00116 template <int p>
00117 inline fixed_point<p> sqrt(fixed_point<p> a);
00118 
00119 template <int p>
00120 inline fixed_point<p> rsqrt(fixed_point<p> a);
00121 
00122 template <int p>
00123 inline fixed_point<p> inv(fixed_point<p> a);
00124 
00125 template <int p>
00126 inline fixed_point<p> abs(fixed_point<p> a)
00127 { 
00128     fixed_point<p> r; 
00129     r.intValue = a.intValue > 0 ? a.intValue : -a.intValue; 
00130     return r; 
00131 }
00132 
00133 // specializations for 16.16 format
00134 
00135 template <>
00136 inline fixed_point<16> sin(fixed_point<16> a)
00137 {
00138     fixed_point<16> r;
00139     r.intValue = fixsin16(a.intValue);
00140     return r;
00141 }
00142 
00143 template <>
00144 inline fixed_point<16> cos(fixed_point<16> a)
00145 {
00146     fixed_point<16> r;
00147     r.intValue = fixcos16(a.intValue);
00148     return r;
00149 }
00150 
00151 
00152 template <>
00153 inline fixed_point<16> sqrt(fixed_point<16> a)
00154 {
00155     fixed_point<16> r;
00156     r.intValue = fixsqrt16(a.intValue);
00157     return r;
00158 }
00159 
00160 template <>
00161 inline fixed_point<16> rsqrt(fixed_point<16> a)
00162 {
00163     fixed_point<16> r;
00164     r.intValue = fixrsqrt16(a.intValue);
00165     return r;
00166 }
00167 
00168 template <>
00169 inline fixed_point<16> inv(fixed_point<16> a)
00170 {
00171     fixed_point<16> r;
00172     r.intValue = fixinv<16>(a.intValue);
00173     return r;
00174 }
00175 
00176 // The multiply accumulate case can be optimized.
00177 template <int p>
00178 inline fixed_point<p> multiply_accumulate(
00179     int count, 
00180     const fixed_point<p> *a,
00181     const fixed_point<p> *b)
00182 {
00183     long long result = 0;
00184     for (int i = 0; i < count; ++i)
00185         result += static_cast<long long>(a[i].intValue) * b[i].intValue;
00186     fixed_point<p> r;
00187     r.intValue = static_cast<int>(result >> p);
00188     return r;
00189 }
00190 
00191 } // end namespace fixedpoint
00192 
00193 #endif
00194