mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 01:39:05 -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. //
|
||||
// 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<IntType, IntBits>::sin_cos(Fixed<IntType, IntBits> const& theta, Fixe
|
||||
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);
|
||||
|
||||
@ -2347,7 +2350,7 @@ template<typename IntType, uint32_t IntBits>
|
||||
inline Fixed<IntType, IntBits> Fixed<IntType, IntBits>::sin() const
|
||||
{
|
||||
Fixed res;
|
||||
sin_cos(*this,&res, 0);
|
||||
sin_cos(*this, &res, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -2355,7 +2358,7 @@ template<typename IntType, uint32_t IntBits>
|
||||
inline Fixed<IntType, IntBits> Fixed<IntType, IntBits>::cos() const
|
||||
{
|
||||
Fixed res;
|
||||
sin_cos(*this,0, &res);
|
||||
sin_cos(*this, 0, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
};
|
||||
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user