mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-01 20:45:18 -05:00
Fixed point utility: implemented fixed_resolution_shift of 16 and 24
This commit is contained in:
parent
de83434405
commit
58f0145705
@ -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<uint64_t>(other>>32);
|
|
||||||
uint64_t const other_lower=static_cast<uint64_t>(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(temp<half_a)
|
|
||||||
{
|
|
||||||
temp<<=1;
|
|
||||||
++shift;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint64_t d=1LL<<shift;
|
|
||||||
if(a_large)
|
|
||||||
{
|
|
||||||
a-=temp;
|
|
||||||
res+=d;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(a && temp && shift)
|
|
||||||
{
|
|
||||||
unsigned right_shift=0;
|
|
||||||
while(right_shift<shift && (temp>a))
|
|
||||||
{
|
|
||||||
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<<max_shift;
|
|
||||||
unsigned b_shift=(max_shift+fixed_resolution_shift)/2;
|
|
||||||
uint64_t a=1LL<<b_shift;
|
|
||||||
|
|
||||||
uint64_t x=m_nVal;
|
|
||||||
|
|
||||||
while(b_shift && a_squared>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):(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<<b_shift);
|
|
||||||
remainder-=delta;
|
|
||||||
if(b_shift)
|
|
||||||
{
|
|
||||||
--b_shift;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fixed(internal(),a);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
int const max_power=63-fixed_resolution_shift;
|
|
||||||
// 35 values (63-28)
|
|
||||||
int64_t const log_two_power_n_reversed[]={
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
// 28 values
|
|
||||||
int64_t const log_one_plus_two_power_minus_n[]={
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
// 28 values
|
|
||||||
int64_t const log_one_over_one_minus_two_power_minus_n[]={
|
|
||||||
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
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fixed fixed::exp() const
|
|
||||||
{
|
|
||||||
if(m_nVal>=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<scale_position)
|
|
||||||
{
|
|
||||||
++left_shift;
|
|
||||||
temp<<=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t res=(left_shift<max_power)?
|
|
||||||
log_two_power_n_reversed[left_shift]:
|
|
||||||
-log_two_power_n_reversed[2*max_power-left_shift];
|
|
||||||
unsigned right_shift=1;
|
|
||||||
uint64_t shifted_temp=temp>>1;
|
|
||||||
while(temp && (right_shift<fixed_resolution_shift))
|
|
||||||
{
|
|
||||||
while((right_shift<fixed_resolution_shift) && (temp<(shifted_temp+scale_position)))
|
|
||||||
{
|
|
||||||
shifted_temp>>=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<<fixed_resolution_shift;
|
|
||||||
|
|
||||||
while((a>=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)<<right_shift;
|
|
||||||
theta->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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,6 +4,9 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. //
|
// Distributed under the Boost Software License, Version 1.0. //
|
||||||
// See: http://www.boost.org/LICENSE_1_0.txt) //
|
// 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 //
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
|
||||||
// //
|
// //
|
||||||
// Modified as fully templatized class with variable size and type internal //
|
// Modified as fully templatized class with variable size and type internal //
|
||||||
@ -740,7 +743,7 @@ void Fixed<IntType, IntBits>::sin_cos(Fixed<IntType, IntBits> const& theta, Fixe
|
|||||||
negate_cos=true;
|
negate_cos=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t x_cos = 1<<28, x_sin = 0;
|
int64_t x_cos = 1<<FixedTraits<IntBits>::fixed_resolution_shift, x_sin = 0;
|
||||||
|
|
||||||
perform_cordic_rotation(x_cos, x_sin, (int64_t) x);
|
perform_cordic_rotation(x_cos, x_sin, (int64_t) x);
|
||||||
|
|
||||||
@ -2347,7 +2350,7 @@ template<typename IntType, uint32_t IntBits>
|
|||||||
inline Fixed<IntType, IntBits> Fixed<IntType, IntBits>::sin() const
|
inline Fixed<IntType, IntBits> Fixed<IntType, IntBits>::sin() const
|
||||||
{
|
{
|
||||||
Fixed res;
|
Fixed res;
|
||||||
sin_cos(*this,&res, 0);
|
sin_cos(*this, &res, 0);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2355,7 +2358,7 @@ template<typename IntType, uint32_t IntBits>
|
|||||||
inline Fixed<IntType, IntBits> Fixed<IntType, IntBits>::cos() const
|
inline Fixed<IntType, IntBits> Fixed<IntType, IntBits>::cos() const
|
||||||
{
|
{
|
||||||
Fixed res;
|
Fixed res;
|
||||||
sin_cos(*this,0, &res);
|
sin_cos(*this, 0, &res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -17,30 +17,401 @@
|
|||||||
|
|
||||||
#include "fixedtraits.h"
|
#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] = {
|
const int64_t FixedTraits<28>::log_two_power_n_reversed[35] = {
|
||||||
0x18429946ELL,0x1791272EFLL,0x16DFB516FLL,0x162E42FF0LL,0x157CD0E70LL,0x14CB5ECF1LL,0x1419ECB71LL,0x13687A9F2LL,
|
0x18429946ELL,
|
||||||
0x12B708872LL,0x1205966F3LL,0x115424573LL,0x10A2B23F4LL,0xFF140274LL,0xF3FCE0F5LL,0xE8E5BF75LL,0xDDCE9DF6LL,
|
0x1791272EFLL,
|
||||||
0xD2B77C76LL,0xC7A05AF7LL,0xBC893977LL,0xB17217F8LL,0xA65AF679LL,0x9B43D4F9LL,0x902CB379LL,0x851591FaLL,
|
0x16DFB516FLL,
|
||||||
0x79FE707bLL,0x6EE74EFbLL,0x63D02D7BLL,0x58B90BFcLL,0x4DA1EA7CLL,0x428AC8FdLL,0x3773A77DLL,0x2C5C85FeLL,
|
0x162E42FF0LL,
|
||||||
0x2145647ELL,0x162E42FfLL,0xB17217FLL
|
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] = {
|
const int64_t FixedTraits<28>::log_one_plus_two_power_minus_n[28] = {
|
||||||
0x67CC8FBLL,0x391FEF9LL,0x1E27077LL,0xF85186LL,
|
0x67CC8FBLL,
|
||||||
0x7E0A6CLL,0x3F8151LL,0x1FE02ALL,0xFF805LL,0x7FE01LL,0x3FF80LL,0x1FFE0LL,0xFFF8LL,
|
0x391FEF9LL,
|
||||||
0x7FFELL,0x4000LL,0x2000LL,0x1000LL,0x800LL,0x400LL,0x200LL,0x100LL,
|
0x1E27077LL,
|
||||||
0x80LL,0x40LL,0x20LL,0x10LL,0x8LL,0x4LL,0x2LL,0x1LL
|
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] = {
|
const int64_t FixedTraits<28>::log_one_over_one_minus_two_power_minus_n[28] = {
|
||||||
0xB172180LL,0x49A5884LL,0x222F1D0LL,0x108598BLL,
|
0xB172180LL,
|
||||||
0x820AECLL,0x408159LL,0x20202BLL,0x100805LL,0x80201LL,0x40080LL,0x20020LL,0x10008LL,
|
0x49A5884LL,
|
||||||
0x8002LL,0x4001LL,0x2000LL,0x1000LL,0x800LL,0x400LL,0x200LL,0x100LL,
|
0x222F1D0LL,
|
||||||
0x80LL,0x40LL,0x20LL,0x10LL,0x8LL,0x4LL,0x2LL,0x1LL
|
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] = {
|
const int64_t FixedTraits<28>::arctantab[32] = {
|
||||||
297197971, 210828714, 124459457, 65760959, 33381290, 16755422, 8385879,
|
297197971,
|
||||||
4193963, 2097109, 1048571, 524287, 262144, 131072, 65536, 32768, 16384,
|
210828714,
|
||||||
8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0, 0,
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
@ -41,4 +41,36 @@ struct FixedTraits<28>
|
|||||||
static const int64_t arctantab[32];
|
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_ */
|
#endif /* SDRBASE_UTIL_FIXEDTRAITS_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user