From 58f014570536653155b6089e7c31aff79fd4dd49 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 4 Feb 2018 01:25:09 +0100 Subject: [PATCH] Fixed point utility: implemented fixed_resolution_shift of 16 and 24 --- sdrbase/util/fixed.cpp | 461 ---------- sdrbase/util/fixed.h | 9 +- sdrbase/util/fixed.hpp | 1591 ---------------------------------- sdrbase/util/fixedtraits.cpp | 403 ++++++++- sdrbase/util/fixedtraits.h | 32 + 5 files changed, 425 insertions(+), 2071 deletions(-) delete mode 100644 sdrbase/util/fixed.cpp delete mode 100644 sdrbase/util/fixed.hpp diff --git a/sdrbase/util/fixed.cpp b/sdrbase/util/fixed.cpp deleted file mode 100644 index 8bc9ddcfd..000000000 --- a/sdrbase/util/fixed.cpp +++ /dev/null @@ -1,461 +0,0 @@ -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// (C) Copyright 2007 Anthony Williams -#include "fixed.hpp" - -// all constants are scaled to 2^28 (as 1) -int64_t const internal_pi=0x3243f6a8; -int64_t const internal_two_pi=0x6487ed51; -int64_t const internal_half_pi=0x1921fb54; -int64_t const internal_quarter_pi=0xc90fdaa; - -extern fixed const fixed_pi(fixed::internal(),internal_pi); -extern fixed const fixed_two_pi(fixed::internal(),internal_two_pi); -extern fixed const fixed_half_pi(fixed::internal(),internal_half_pi); -extern fixed const fixed_quarter_pi(fixed::internal(),internal_quarter_pi); - -fixed& fixed::operator%=(fixed const& other) -{ - m_nVal = m_nVal%other.m_nVal; - return *this; -} - -fixed& fixed::operator*=(fixed const& val) -{ - bool const val_negative=val.m_nVal<0; - bool const this_negative=m_nVal<0; - bool const negate=val_negative ^ this_negative; - uint64_t const other=val_negative?-val.m_nVal:val.m_nVal; - uint64_t const self=this_negative?-m_nVal:m_nVal; - - if(uint64_t const self_upper=(self>>32)) - { - m_nVal=(self_upper*other)<<(32-fixed_resolution_shift); - } - else - { - m_nVal=0; - } - if(uint64_t const self_lower=(self&0xffffffff)) - { - uint64_t const other_upper=static_cast(other>>32); - uint64_t const other_lower=static_cast(other&0xffffffff); - uint64_t const lower_self_upper_other_res=self_lower*other_upper; - uint64_t const lower_self_lower_other_res=self_lower*other_lower; - m_nVal+=(lower_self_upper_other_res<<(32-fixed_resolution_shift)) - + (lower_self_lower_other_res>>fixed_resolution_shift); - } - - if(negate) - { - m_nVal=-m_nVal; - } - return *this; -} - - -fixed& fixed::operator/=(fixed const& divisor) -{ - if( !divisor.m_nVal) - { - m_nVal=fixed_max.m_nVal; - } - else - { - bool const negate_this=(m_nVal<0); - bool const negate_divisor=(divisor.m_nVal<0); - bool const negate=negate_this ^ negate_divisor; - uint64_t a=negate_this?-m_nVal:m_nVal; - uint64_t b=negate_divisor?-divisor.m_nVal:divisor.m_nVal; - - uint64_t res=0; - - uint64_t temp=b; - bool const a_large=a>b; - unsigned shift=fixed_resolution_shift; - - if(a_large) - { - uint64_t const half_a=a>>1; - while(tempa)) - { - temp>>=1; - ++right_shift; - } - d>>=right_shift; - shift-=right_shift; - a-=temp; - res+=d; - } - m_nVal=(negate?-(int64_t)res:res); - } - - return *this; -} - - -fixed fixed::sqrt() const -{ - unsigned const max_shift=62; - uint64_t a_squared=1LL<x) - { - a>>=1; - a_squared>>=2; - --b_shift; - } - - uint64_t remainder=x-a_squared; - --b_shift; - - while(remainder && b_shift) - { - uint64_t b_squared=1LL<<(2*b_shift-fixed_resolution_shift); - int const two_a_b_shift=b_shift+1-fixed_resolution_shift; - uint64_t two_a_b=(two_a_b_shift>0)?(a<>-two_a_b_shift); - - while(b_shift && remainder<(b_squared+two_a_b)) - { - b_squared>>=2; - two_a_b>>=1; - --b_shift; - } - uint64_t const delta=b_squared+two_a_b; - if((2*remainder)>delta) - { - a+=(1LL<=log_two_power_n_reversed[0]) - { - return fixed_max; - } - if(m_nVal<-log_two_power_n_reversed[63-2*fixed_resolution_shift]) - { - return fixed(internal(),0); - } - if(!m_nVal) - { - return fixed(internal(),fixed_resolution); - } - - int64_t res=fixed_resolution; - - if(m_nVal>0) - { - int power=max_power; - int64_t const* log_entry=log_two_power_n_reversed; - int64_t temp=m_nVal; - while(temp && power>(-(int)fixed_resolution_shift)) - { - while(!power || (temp<*log_entry)) - { - if(!power) - { - log_entry=log_one_plus_two_power_minus_n; - } - else - { - ++log_entry; - } - --power; - } - temp-=*log_entry; - if(power<0) - { - res+=(res>>(-power)); - } - else - { - res<<=power; - } - } - } - else - { - int power=fixed_resolution_shift; - int64_t const* log_entry=log_two_power_n_reversed+(max_power-power); - int64_t temp=m_nVal; - - while(temp && power>(-(int)fixed_resolution_shift)) - { - while(!power || (temp>(-*log_entry))) - { - if(!power) - { - log_entry=log_one_over_one_minus_two_power_minus_n; - } - else - { - ++log_entry; - } - --power; - } - temp+=*log_entry; - if(power<0) - { - res-=(res>>(-power)); - } - else - { - res>>=power; - } - } - } - - return fixed(internal(),res); -} - -fixed fixed::log() const -{ - if(m_nVal<=0) - { - return -fixed_max; - } - if(m_nVal==fixed_resolution) - { - return fixed_zero; - } - uint64_t temp=m_nVal; - int left_shift=0; - uint64_t const scale_position=0x8000000000000000; - while(temp>1; - while(temp && (right_shift>=1; - ++right_shift; - } - - temp-=shifted_temp; - shifted_temp=temp>>right_shift; - res+=log_one_over_one_minus_two_power_minus_n[right_shift-1]; - } - return fixed(fixed::internal(),res); -} - - -namespace -{ - const int64_t arctantab[32] = { - 297197971, 210828714, 124459457, 65760959, 33381290, 16755422, 8385879, - 4193963, 2097109, 1048571, 524287, 262144, 131072, 65536, 32768, 16384, - 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0, 0, - }; - - - int64_t scale_cordic_result(int64_t a) - { - int64_t const cordic_scale_factor=0x22C2DD1C; /* 0.271572 * 2^31*/ - return (int64_t)((((int64_t)a)*cordic_scale_factor)>>31); - } - - int64_t right_shift(int64_t val,int shift) - { - return (shift<0)?(val<<-shift):(val>>shift); - } - - void perform_cordic_rotation(int64_t&px, int64_t&py, int64_t theta) - { - int64_t x = px, y = py; - int64_t const *arctanptr = arctantab; - for (int i = -1; i <= (int)fixed_resolution_shift; ++i) - { - int64_t const yshift=right_shift(y,i); - int64_t const xshift=right_shift(x,i); - - if (theta < 0) - { - x += yshift; - y -= xshift; - theta += *arctanptr++; - } - else - { - x -= yshift; - y += xshift; - theta -= *arctanptr++; - } - } - px = scale_cordic_result(x); - py = scale_cordic_result(y); - } - - - void perform_cordic_polarization(int64_t& argx, int64_t&argy) - { - int64_t theta=0; - int64_t x = argx, y = argy; - int64_t const *arctanptr = arctantab; - for(int i = -1; i <= (int)fixed_resolution_shift; ++i) - { - int64_t const yshift=right_shift(y,i); - int64_t const xshift=right_shift(x,i); - if(y < 0) - { - y += xshift; - x -= yshift; - theta -= *arctanptr++; - } - else - { - y -= xshift; - x += yshift; - theta += *arctanptr++; - } - } - argx = scale_cordic_result(x); - argy = theta; - } -} - -void fixed::sin_cos(fixed const& theta,fixed* s,fixed*c) -{ - int64_t x=theta.m_nVal%internal_two_pi; - if( x < 0 ) - x += internal_two_pi; - - bool negate_cos=false; - bool negate_sin=false; - - if( x > internal_pi ) - { - x =internal_two_pi-x; - negate_sin=true; - } - if(x>internal_half_pi) - { - x=internal_pi-x; - negate_cos=true; - } - int64_t x_cos=1<<28,x_sin=0; - - perform_cordic_rotation(x_cos,x_sin,(int64_t)x); - - if(s) - { - s->m_nVal=negate_sin?-x_sin:x_sin; - } - if(c) - { - c->m_nVal=negate_cos?-x_cos:x_cos; - } -} - -fixed fixed::atan() const -{ - fixed r,theta; - to_polar(1,*this,&r,&theta); - return theta; -} - -void fixed::to_polar(fixed const& x,fixed const& y,fixed* r,fixed*theta) -{ - bool const negative_x=x.m_nVal<0; - bool const negative_y=y.m_nVal<0; - - uint64_t a=negative_x?-x.m_nVal:x.m_nVal; - uint64_t b=negative_y?-y.m_nVal:y.m_nVal; - - unsigned right_shift=0; - unsigned const max_value=1U<=max_value) || (b>=max_value)) - { - ++right_shift; - a>>=1; - b>>=1; - } - int64_t xtemp=(int64_t)a; - int64_t ytemp=(int64_t)b; - perform_cordic_polarization(xtemp,ytemp); - r->m_nVal=int64_t(xtemp)<m_nVal=ytemp; - - if(negative_x && negative_y) - { - theta->m_nVal-=internal_pi; - } - else if(negative_x) - { - theta->m_nVal=internal_pi-theta->m_nVal; - } - else if(negative_y) - { - theta->m_nVal=-theta->m_nVal; - } -} - diff --git a/sdrbase/util/fixed.h b/sdrbase/util/fixed.h index 6cc3a5d19..96193212b 100644 --- a/sdrbase/util/fixed.h +++ b/sdrbase/util/fixed.h @@ -4,6 +4,9 @@ // Distributed under the Boost Software License, Version 1.0. // // See: http://www.boost.org/LICENSE_1_0.txt) // // // +// Original article: // +// http://www.drdobbs.com/cpp/optimizing-math-intensive-applications-w/207000448 // +// // // Copyright (C) 2018 Edouard Griffiths, F4EXB // // // // Modified as fully templatized class with variable size and type internal // @@ -740,7 +743,7 @@ void Fixed::sin_cos(Fixed const& theta, Fixe negate_cos=true; } - int64_t x_cos = 1<<28, x_sin = 0; + int64_t x_cos = 1<::fixed_resolution_shift, x_sin = 0; perform_cordic_rotation(x_cos, x_sin, (int64_t) x); @@ -2347,7 +2350,7 @@ template inline Fixed Fixed::sin() const { Fixed res; - sin_cos(*this,&res, 0); + sin_cos(*this, &res, 0); return res; } @@ -2355,7 +2358,7 @@ template inline Fixed Fixed::cos() const { Fixed res; - sin_cos(*this,0, &res); + sin_cos(*this, 0, &res); return res; } diff --git a/sdrbase/util/fixed.hpp b/sdrbase/util/fixed.hpp deleted file mode 100644 index b9f97bd01..000000000 --- a/sdrbase/util/fixed.hpp +++ /dev/null @@ -1,1591 +0,0 @@ -#ifndef FIXED_HPP -#define FIXED_HPP -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// (C) Copyright 2007 Anthony Williams - -#include -#include -#include - -// Internally 1 is 2^28. 28 is the highest power of two that can represent 9.99999... safely on 64 bits internally - -unsigned const fixed_resolution_shift=28; -int64_t const fixed_resolution=1LL<(nVal*static_cast(fixed_resolution))) - {} - fixed(float nVal): - m_nVal(static_cast(nVal*static_cast(fixed_resolution))) - {} - - template - fixed& operator=(T other) - { - m_nVal=fixed(other).m_nVal; - return *this; - } - fixed& operator=(fixed const& other) - { - m_nVal=other.m_nVal; - return *this; - } - friend bool operator==(fixed const& lhs,fixed const& rhs) - { - return lhs.m_nVal==rhs.m_nVal; - } - friend bool operator!=(fixed const& lhs,fixed const& rhs) - { - return lhs.m_nVal!=rhs.m_nVal; - } - friend bool operator<(fixed const& lhs,fixed const& rhs) - { - return lhs.m_nVal(fixed const& lhs,fixed const& rhs) - { - return lhs.m_nVal>rhs.m_nVal; - } - friend bool operator<=(fixed const& lhs,fixed const& rhs) - { - return lhs.m_nVal<=rhs.m_nVal; - } - friend bool operator>=(fixed const& lhs,fixed const& rhs) - { - return lhs.m_nVal>=rhs.m_nVal; - } - operator bool() const - { - return m_nVal?true:false; - } - inline operator double() const - { - return as_double(); - } - int64_t as_internal() const - { - return m_nVal; - } - float as_float() const - { - return m_nVal/(float)fixed_resolution; - } - - double as_double() const - { - return m_nVal/(double)fixed_resolution; - } - - int64_t as_long() const - { - return (int64_t)(m_nVal/fixed_resolution); - } - int64_t as_int64() const - { - return m_nVal/fixed_resolution; - } - - int as_int() const - { - return (int)(m_nVal/fixed_resolution); - } - - uint64_t as_unsigned_long() const - { - return (uint64_t)(m_nVal/fixed_resolution); - } - uint64_t as_unsigned_int64() const - { - return (uint64_t)m_nVal/fixed_resolution; - } - - unsigned int as_unsigned_int() const - { - return (unsigned int)(m_nVal/fixed_resolution); - } - - short as_short() const - { - return (short)(m_nVal/fixed_resolution); - } - - unsigned short as_unsigned_short() const - { - return (unsigned short)(m_nVal/fixed_resolution); - } - - fixed operator++() - { - m_nVal += fixed_resolution; - return *this; - } - - fixed operator--() - { - m_nVal -= fixed_resolution; - return *this; - } - - fixed floor() const; - fixed ceil() const; - fixed sqrt() const; - fixed exp() const; - fixed log() const; - fixed& operator%=(fixed const& other); - fixed& operator*=(fixed const& val); - fixed& operator/=(fixed const& val); - fixed& operator-=(fixed const& val) - { - m_nVal -= val.m_nVal; - return *this; - } - - fixed& operator+=(fixed const& val) - { - m_nVal += val.m_nVal; - return *this; - } - fixed& operator*=(double val) - { - return (*this)*=fixed(val); - } - fixed& operator*=(float val) - { - return (*this)*=fixed(val); - } - fixed& operator*=(int64_t val) - { - m_nVal*=val; - return *this; - } - fixed& operator*=(int val) - { - m_nVal*=val; - return *this; - } - fixed& operator*=(short val) - { - m_nVal*=val; - return *this; - } - fixed& operator*=(char val) - { - m_nVal*=val; - return *this; - } - fixed& operator*=(uint64_t val) - { - m_nVal*=val; - return *this; - } - fixed& operator*=(unsigned int val) - { - m_nVal*=val; - return *this; - } - fixed& operator*=(unsigned short val) - { - m_nVal*=val; - return *this; - } - fixed& operator*=(unsigned char val) - { - m_nVal*=val; - return *this; - } - fixed& operator/=(double val) - { - return (*this)/=fixed(val); - } - fixed& operator/=(float val) - { - return (*this)/=fixed(val); - } - fixed& operator/=(int64_t val) - { - m_nVal/=val; - return *this; - } - fixed& operator/=(int val) - { - m_nVal/=val; - return *this; - } - fixed& operator/=(short val) - { - m_nVal/=val; - return *this; - } - fixed& operator/=(char val) - { - m_nVal/=val; - return *this; - } - fixed& operator/=(uint64_t val) - { - m_nVal/=val; - return *this; - } - fixed& operator/=(unsigned int val) - { - m_nVal/=val; - return *this; - } - fixed& operator/=(unsigned short val) - { - m_nVal/=val; - return *this; - } - fixed& operator/=(unsigned char val) - { - m_nVal/=val; - return *this; - } - - - bool operator!() const - { - return m_nVal==0; - } - - fixed modf(fixed* integral_part) const; - fixed atan() const; - - static void sin_cos(fixed const& theta,fixed* s,fixed*c); - static void to_polar(fixed const& x,fixed const& y,fixed* r,fixed*theta); - - fixed sin() const; - fixed cos() const; - fixed tan() const; - fixed operator-() const; - fixed abs() const; -}; - -/* why always as double ? -inline std::ostream& operator<<(std::ostream& os,fixed const& value) -{ - return os<(double a, fixed const& b) -{ - return fixed(a)>b; -} -inline bool operator>(float a, fixed const& b) -{ - return fixed(a)>b; -} - -inline bool operator>(uint64_t a, fixed const& b) -{ - return fixed(a)>b; -} -inline bool operator>(int64_t a, fixed const& b) -{ - return fixed(a)>b; -} -inline bool operator>(unsigned a, fixed const& b) -{ - return fixed(a)>b; -} -inline bool operator>(int a, fixed const& b) -{ - return fixed(a)>b; -} -inline bool operator>(unsigned short a, fixed const& b) -{ - return fixed(a)>b; -} -inline bool operator>(short a, fixed const& b) -{ - return fixed(a)>b; -} -inline bool operator>(unsigned char a, fixed const& b) -{ - return fixed(a)>b; -} -inline bool operator>(char a, fixed const& b) -{ - return fixed(a)>b; -} - -inline bool operator>(fixed const& a,double b) -{ - return a>fixed(b); -} -inline bool operator>(fixed const& a,float b) -{ - return a>fixed(b); -} -inline bool operator>(fixed const& a,uint64_t b) -{ - return a>fixed(b); -} -inline bool operator>(fixed const& a,int64_t b) -{ - return a>fixed(b); -} -inline bool operator>(fixed const& a,unsigned b) -{ - return a>fixed(b); -} -inline bool operator>(fixed const& a,int b) -{ - return a>fixed(b); -} -inline bool operator>(fixed const& a,unsigned short b) -{ - return a>fixed(b); -} -inline bool operator>(fixed const& a,short b) -{ - return a>fixed(b); -} -inline bool operator>(fixed const& a,unsigned char b) -{ - return a>fixed(b); -} -inline bool operator>(fixed const& a,char b) -{ - return a>fixed(b); -} - -inline bool operator<=(double a, fixed const& b) -{ - return fixed(a)<=b; -} -inline bool operator<=(float a, fixed const& b) -{ - return fixed(a)<=b; -} - -inline bool operator<=(uint64_t a, fixed const& b) -{ - return fixed(a)<=b; -} -inline bool operator<=(int64_t a, fixed const& b) -{ - return fixed(a)<=b; -} -inline bool operator<=(unsigned a, fixed const& b) -{ - return fixed(a)<=b; -} -inline bool operator<=(int a, fixed const& b) -{ - return fixed(a)<=b; -} -inline bool operator<=(unsigned short a, fixed const& b) -{ - return fixed(a)<=b; -} -inline bool operator<=(short a, fixed const& b) -{ - return fixed(a)<=b; -} -inline bool operator<=(unsigned char a, fixed const& b) -{ - return fixed(a)<=b; -} -inline bool operator<=(char a, fixed const& b) -{ - return fixed(a)<=b; -} - -inline bool operator<=(fixed const& a,double b) -{ - return a<=fixed(b); -} -inline bool operator<=(fixed const& a,float b) -{ - return a<=fixed(b); -} -inline bool operator<=(fixed const& a,uint64_t b) -{ - return a<=fixed(b); -} -inline bool operator<=(fixed const& a,int64_t b) -{ - return a<=fixed(b); -} -inline bool operator<=(fixed const& a,unsigned b) -{ - return a<=fixed(b); -} -inline bool operator<=(fixed const& a,int b) -{ - return a<=fixed(b); -} -inline bool operator<=(fixed const& a,unsigned short b) -{ - return a<=fixed(b); -} -inline bool operator<=(fixed const& a,short b) -{ - return a<=fixed(b); -} -inline bool operator<=(fixed const& a,unsigned char b) -{ - return a<=fixed(b); -} -inline bool operator<=(fixed const& a,char b) -{ - return a<=fixed(b); -} - -inline bool operator>=(double a, fixed const& b) -{ - return fixed(a)>=b; -} -inline bool operator>=(float a, fixed const& b) -{ - return fixed(a)>=b; -} - -inline bool operator>=(uint64_t a, fixed const& b) -{ - return fixed(a)>=b; -} -inline bool operator>=(int64_t a, fixed const& b) -{ - return fixed(a)>=b; -} -inline bool operator>=(unsigned a, fixed const& b) -{ - return fixed(a)>=b; -} -inline bool operator>=(int a, fixed const& b) -{ - return fixed(a)>=b; -} -inline bool operator>=(unsigned short a, fixed const& b) -{ - return fixed(a)>=b; -} -inline bool operator>=(short a, fixed const& b) -{ - return fixed(a)>=b; -} -inline bool operator>=(unsigned char a, fixed const& b) -{ - return fixed(a)>=b; -} -inline bool operator>=(char a, fixed const& b) -{ - return fixed(a)>=b; -} - -inline bool operator>=(fixed const& a,double b) -{ - return a>=fixed(b); -} -inline bool operator>=(fixed const& a,float b) -{ - return a>=fixed(b); -} -inline bool operator>=(fixed const& a, uint64_t b) -{ - return a>=fixed(b); -} -inline bool operator>=(fixed const& a, int64_t b) -{ - return a>=fixed(b); -} -inline bool operator>=(fixed const& a,unsigned b) -{ - return a>=fixed(b); -} -inline bool operator>=(fixed const& a,int b) -{ - return a>=fixed(b); -} -inline bool operator>=(fixed const& a,unsigned short b) -{ - return a>=fixed(b); -} -inline bool operator>=(fixed const& a,short b) -{ - return a>=fixed(b); -} -inline bool operator>=(fixed const& a,unsigned char b) -{ - return a>=fixed(b); -} -inline bool operator>=(fixed const& a,char b) -{ - return a>=fixed(b); -} - -inline fixed sin(fixed const& x) -{ - return x.sin(); -} -inline fixed cos(fixed const& x) -{ - return x.cos(); -} -inline fixed tan(fixed const& x) -{ - return x.tan(); -} - -inline fixed sqrt(fixed const& x) -{ - return x.sqrt(); -} - -inline fixed exp(fixed const& x) -{ - return x.exp(); -} - -inline fixed log(fixed const& x) -{ - return x.log(); -} - -inline fixed floor(fixed const& x) -{ - return x.floor(); -} - -inline fixed ceil(fixed const& x) -{ - return x.ceil(); -} - -inline fixed abs(fixed const& x) -{ - return x.abs(); -} - -inline fixed modf(fixed const& x,fixed*integral_part) -{ - return x.modf(integral_part); -} - -inline fixed fixed::ceil() const -{ - if(m_nVal%fixed_resolution) - { - return floor()+1; - } - else - { - return *this; - } -} - -inline fixed fixed::floor() const -{ - fixed res(*this); - int64_t const remainder=m_nVal%fixed_resolution; - if(remainder) - { - res.m_nVal-=remainder; - if(m_nVal<0) - { - res-=1; - } - } - return res; -} - - -inline fixed fixed::sin() const -{ - fixed res; - sin_cos(*this,&res,0); - return res; -} - -inline fixed fixed::cos() const -{ - fixed res; - sin_cos(*this,0,&res); - return res; -} - -inline fixed fixed::tan() const -{ - fixed s,c; - sin_cos(*this,&s,&c); - return s/c; -} - -inline fixed fixed::operator-() const -{ - return fixed(internal(),-m_nVal); -} - -inline fixed fixed::abs() const -{ - return fixed(internal(),m_nVal<0?-m_nVal:m_nVal); -} - -inline fixed fixed::modf(fixed*integral_part) const -{ - int64_t fractional_part=m_nVal%fixed_resolution; - if(m_nVal<0 && fractional_part>0) - { - fractional_part-=fixed_resolution; - } - integral_part->m_nVal=m_nVal-fractional_part; - return fixed(internal(),fractional_part); -} - -inline fixed arg(const std::complex& val) -{ - fixed r,theta; - fixed::to_polar(val.real(),val.imag(),&r,&theta); - return theta; -} - -inline std::complex polar(fixed const& rho, fixed const& theta) -{ - fixed s,c; - fixed::sin_cos(theta,&s,&c); - return std::complex(rho * c, rho * s); -} - -fixed const fixed_max(fixed::internal(),0x7fffffffffffffffLL); -fixed const fixed_one(fixed::internal(),1LL<<(fixed_resolution_shift)); -fixed const fixed_zero(fixed::internal(),0); -fixed const fixed_half(fixed::internal(),1LL<<(fixed_resolution_shift-1)); -extern fixed const fixed_pi; -extern fixed const fixed_two_pi; -extern fixed const fixed_half_pi; -extern fixed const fixed_quarter_pi; - -#endif diff --git a/sdrbase/util/fixedtraits.cpp b/sdrbase/util/fixedtraits.cpp index 168b260c0..095e58882 100644 --- a/sdrbase/util/fixedtraits.cpp +++ b/sdrbase/util/fixedtraits.cpp @@ -17,30 +17,401 @@ #include "fixedtraits.h" +// 1.0 = 2^28 internal representation + +// ln(1/2^n), n = index+1 then list is reversed const int64_t FixedTraits<28>::log_two_power_n_reversed[35] = { - 0x18429946ELL,0x1791272EFLL,0x16DFB516FLL,0x162E42FF0LL,0x157CD0E70LL,0x14CB5ECF1LL,0x1419ECB71LL,0x13687A9F2LL, - 0x12B708872LL,0x1205966F3LL,0x115424573LL,0x10A2B23F4LL,0xFF140274LL,0xF3FCE0F5LL,0xE8E5BF75LL,0xDDCE9DF6LL, - 0xD2B77C76LL,0xC7A05AF7LL,0xBC893977LL,0xB17217F8LL,0xA65AF679LL,0x9B43D4F9LL,0x902CB379LL,0x851591FaLL, - 0x79FE707bLL,0x6EE74EFbLL,0x63D02D7BLL,0x58B90BFcLL,0x4DA1EA7CLL,0x428AC8FdLL,0x3773A77DLL,0x2C5C85FeLL, - 0x2145647ELL,0x162E42FfLL,0xB17217FLL + 0x18429946ELL, + 0x1791272EFLL, + 0x16DFB516FLL, + 0x162E42FF0LL, + 0x157CD0E70LL, + 0x14CB5ECF1LL, + 0x1419ECB71LL, + 0x13687A9F2LL, + 0x12B708872LL, + 0x1205966F3LL, + 0x115424573LL, + 0x10A2B23F4LL, + 0xFF140274LL, + 0xF3FCE0F5LL, + 0xE8E5BF75LL, + 0xDDCE9DF6LL, + 0xD2B77C76LL, + 0xC7A05AF7LL, + 0xBC893977LL, + 0xB17217F8LL, + 0xA65AF679LL, + 0x9B43D4F9LL, + 0x902CB379LL, + 0x851591FaLL, + 0x79FE707bLL, + 0x6EE74EFbLL, + 0x63D02D7BLL, + 0x58B90BFcLL, + 0x4DA1EA7CLL, + 0x428AC8FdLL, + 0x3773A77DLL, + 0x2C5C85FeLL, + 0x2145647ELL, + 0x162E42FfLL, + 0xB17217FLL }; +// ln(1+2^-n), n = index+1 const int64_t FixedTraits<28>::log_one_plus_two_power_minus_n[28] = { - 0x67CC8FBLL,0x391FEF9LL,0x1E27077LL,0xF85186LL, - 0x7E0A6CLL,0x3F8151LL,0x1FE02ALL,0xFF805LL,0x7FE01LL,0x3FF80LL,0x1FFE0LL,0xFFF8LL, - 0x7FFELL,0x4000LL,0x2000LL,0x1000LL,0x800LL,0x400LL,0x200LL,0x100LL, - 0x80LL,0x40LL,0x20LL,0x10LL,0x8LL,0x4LL,0x2LL,0x1LL + 0x67CC8FBLL, + 0x391FEF9LL, + 0x1E27077LL, + 0xF85186LL, + 0x7E0A6CLL, + 0x3F8151LL, + 0x1FE02ALL, + 0xFF805LL, + 0x7FE01LL, + 0x3FF80LL, + 0x1FFE0LL, + 0xFFF8LL, + 0x7FFELL, + 0x4000LL, + 0x2000LL, + 0x1000LL, + 0x800LL, + 0x400LL, + 0x200LL, + 0x100LL, + 0x80LL, + 0x40LL, + 0x20LL, + 0x10LL, + 0x8LL, + 0x4LL, + 0x2LL, + 0x1LL }; +// ln(1/1-2^-n), n = index+1 const int64_t FixedTraits<28>::log_one_over_one_minus_two_power_minus_n[28] = { - 0xB172180LL,0x49A5884LL,0x222F1D0LL,0x108598BLL, - 0x820AECLL,0x408159LL,0x20202BLL,0x100805LL,0x80201LL,0x40080LL,0x20020LL,0x10008LL, - 0x8002LL,0x4001LL,0x2000LL,0x1000LL,0x800LL,0x400LL,0x200LL,0x100LL, - 0x80LL,0x40LL,0x20LL,0x10LL,0x8LL,0x4LL,0x2LL,0x1LL + 0xB172180LL, + 0x49A5884LL, + 0x222F1D0LL, + 0x108598BLL, + 0x820AECLL, + 0x408159LL, + 0x20202BLL, + 0x100805LL, + 0x80201LL, + 0x40080LL, + 0x20020LL, + 0x10008LL, + 0x8002LL, + 0x4001LL, + 0x2000LL, + 0x1000LL, + 0x800LL, + 0x400LL, + 0x200LL, + 0x100LL, + 0x80LL, + 0x40LL, + 0x20LL, + 0x10LL, + 0x8LL, + 0x4LL, + 0x2LL, + 0x1LL }; const int64_t FixedTraits<28>::arctantab[32] = { - 297197971, 210828714, 124459457, 65760959, 33381290, 16755422, 8385879, - 4193963, 2097109, 1048571, 524287, 262144, 131072, 65536, 32768, 16384, - 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0, 0, + 297197971, + 210828714, + 124459457, + 65760959, + 33381290, + 16755422, + 8385879, + 4193963, + 2097109, + 1048571, + 524287, + 262144, + 131072, + 65536, + 32768, + 16384, + 8192, + 4096, + 2048, + 1024, + 512, + 256, + 128, + 64, + 32, + 16, + 8, + 4, + 2, + 1, + 0, + 0 }; + +// 1.0 = 2^16 internal representation + +const int64_t FixedTraits<16>::log_two_power_n_reversed[47] = { + 2135026LL, + 2089600LL, + 2044174LL, + 1998748LL, + 1953322LL, + 1907896LL, + 1862470LL, + 1817044LL, + 1771618LL, + 1726192LL, + 1680765LL, + 1635339LL, + 1589913LL, + 1544487LL, + 1499061LL, + 1453635LL, + 1408209LL, + 1362783LL, + 1317357LL, + 1271931LL, + 1226505LL, + 1181078LL, + 1135652LL, + 1090226LL, + 1044800LL, + 999374LL, + 953948LL, + 908522LL, + 863096LL, + 817670LL, + 772244LL, + 726817LL, + 681391LL, + 635965LL, + 590539LL, + 545113LL, + 499687LL, + 454261LL, + 408835LL, + 363409LL, + 317983LL, + 272557LL, + 227130LL, + 181704LL, + 136278LL, + 90852LL, + 45426LL +}; + +const int64_t FixedTraits<16>::log_one_plus_two_power_minus_n[16] = { + 26573LL, + 14624LL, + 7719LL, + 3973LL, + 2017LL, + 1016LL, + 510LL, + 256LL, + 128LL, + 64LL, + 32LL, + 16LL, + 8LL, + 4LL, + 2LL, + 1LL +}; + +const int64_t FixedTraits<16>::log_one_over_one_minus_two_power_minus_n[16] = { + 45426LL, + 18854LL, + 8751LL, + 4230LL, + 2081LL, + 1032LL, + 514LL, + 257LL, + 128LL, + 64LL, + 32LL, + 16LL, + 8LL, + 4LL, + 2LL, + 1LL +}; + +const int64_t FixedTraits<16>::arctantab[32] = { + 72558LL, + 51471LL, + 30385LL, + 16054LL, + 8149LL, + 4090LL, + 2047LL, + 1023LL, + 511LL, + 255LL, + 127LL, + 64LL, + 32LL, + 16LL, + 8LL, + 4LL, + 2LL, + 1LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL +}; + +// 1.0 = 2^24 internal representation + +const int64_t FixedTraits<24>::log_two_power_n_reversed[39] = { + 453534119LL, + 441905039LL, + 430275959LL, + 418646879LL, + 407017799LL, + 395388719LL, + 383759639LL, + 372130559LL, + 360501479LL, + 348872399LL, + 337243319LL, + 325614239LL, + 313985159LL, + 302356079LL, + 290726999LL, + 279097919LL, + 267468839LL, + 255839759LL, + 244210679LL, + 232581599LL, + 220952519LL, + 209323439LL, + 197694359LL, + 186065279LL, + 174436200LL, + 162807120LL, + 151178040LL, + 139548960LL, + 127919880LL, + 116290800LL, + 104661720LL, + 93032640LL, + 81403560LL, + 69774480LL, + 58145400LL, + 46516320LL, + 34887240LL, + 23258160LL, + 11629080LL +}; + +const int64_t FixedTraits<24>::log_one_plus_two_power_minus_n[24] = { + 6802576LL, + 3743728LL, + 1976071LL, + 1017112LL, + 516263LL, + 260117LL, + 130563LL, + 65408LL, + 32736LL, + 16376LL, + 8190LL, + 4096LL, + 2048LL, + 1024LL, + 512LL, + 256LL, + 128LL, + 64LL, + 32LL, + 16LL, + 8LL, + 4LL, + 2LL, + 1LL +}; + +const int64_t FixedTraits<24>::log_one_over_one_minus_two_power_minus_n[24] = { + 11629080LL, + 4826504LL, + 2240285LL, + 1082777LL, + 532655LL, + 264214LL, + 131587LL, + 65664LL, + 32800LL, + 16392LL, + 8194LL, + 4097LL, + 2048LL, + 1024LL, + 512LL, + 256LL, + 128LL, + 64LL, + 32LL, + 16LL, + 8LL, + 4LL, + 2LL, + 1LL +}; + +const int64_t FixedTraits<24>::arctantab[32] = { + 18574873LL, + 13176794LL, + 7778716LL, + 4110059LL, + 2086330LL, + 1047213LL, + 524117LL, + 262122LL, + 131069LL, + 65535LL, + 32767LL, + 16384LL, + 8192LL, + 4096LL, + 2048LL, + 1024LL, + 512LL, + 256LL, + 128LL, + 64LL, + 32LL, + 16LL, + 8LL, + 4LL, + 2LL, + 1LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL, + 0LL +}; + diff --git a/sdrbase/util/fixedtraits.h b/sdrbase/util/fixedtraits.h index 5b2d26be5..db53bb2cf 100644 --- a/sdrbase/util/fixedtraits.h +++ b/sdrbase/util/fixedtraits.h @@ -41,4 +41,36 @@ struct FixedTraits<28> static const int64_t arctantab[32]; }; +template<> +struct FixedTraits<16> +{ + static const uint32_t fixed_resolution_shift = 16; + static const int64_t fixed_resolution = 1LL << fixed_resolution_shift; + static const int32_t max_power = 63 - fixed_resolution_shift; + static const int64_t internal_pi = 205887; + static const int64_t internal_two_pi = 411775; + static const int64_t internal_half_pi = 102944; + static const int64_t internal_quarter_pi = 51472; + static const int64_t log_two_power_n_reversed[47]; // 47 = 63 - 16 + static const int64_t log_one_plus_two_power_minus_n[16]; + static const int64_t log_one_over_one_minus_two_power_minus_n[16]; + static const int64_t arctantab[32]; +}; + +template<> +struct FixedTraits<24> +{ + static const uint32_t fixed_resolution_shift = 24; + static const int64_t fixed_resolution = 1LL << fixed_resolution_shift; + static const int32_t max_power = 63 - fixed_resolution_shift; + static const int64_t internal_pi = 52707179; + static const int64_t internal_two_pi = 105414357; + static const int64_t internal_half_pi = 26353589; + static const int64_t internal_quarter_pi = 13176795; + static const int64_t log_two_power_n_reversed[39]; // 39 = 63 - 16 + static const int64_t log_one_plus_two_power_minus_n[24]; + static const int64_t log_one_over_one_minus_two_power_minus_n[24]; + static const int64_t arctantab[32]; +}; + #endif /* SDRBASE_UTIL_FIXEDTRAITS_H_ */