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.
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
Generated on Sat Jul 23 2022 12:09:06 by 1.7.2