📄 fix.h
字号:
#ifndef _FIX_H
#define _FIX_H
#include <assert.h>
typedef int Fix_t;
#define FIX_SHIFT 8
#define Fix_toInt(x) ( (x)>>FIX_SHIFT )
#define Fix_int(i) ( Fix_t(i)<<FIX_SHIFT )
#define Fix_float(i) ( Fix_t(float(i)*float(1<<FIX_SHIFT)) )
#define Fix_mul(a,b) ( ((a)*(b))>>FIX_SHIFT ) //Overflow-risky
#define Fix_div(a,b) ( ((a)<<FIX_SHIFT)/(b) ) //Overflow-risky
#define Fixf(i) ( Fix(Fix_t(float(i)*float(1<<FIX_SHIFT))) )
#define Fix_PI ( Fix(Fix_t(float(3.1415926)*float(1<<FIX_SHIFT))) )
#define Fix_PIper2 ( Fix(Fix_t(float(1.5707963)*float(1<<FIX_SHIFT))) )
#define Fix_PIper4 ( Fix(Fix_t(float(0.7853981)*float(1<<FIX_SHIFT))) )
#define Fix_radToDeg ( Fix(Fix_t(float(180.0/3.1415926)*float(1<<FIX_SHIFT))) )
class Fix
{
public:
enum { SIN_SIZE = 1024 };
Fix_t v;
Fix() {}
explicit Fix( int x ) : v(x) {}
void setFraction( Fix f ) {v &= -1<<FIX_SHIFT; v += f.v & ((1<<FIX_SHIFT)-1);}
Fix& operator+=( const Fix& o ) {v += o.v; return *this;}
Fix& operator-=( const Fix& o ) {v -= o.v; return *this;}
Fix& operator*=( const Fix& o ) {v = mul(v,o.v); return *this;}
Fix& operator/=( const Fix& o ) {assert(o.v != 0); v = div(v,o.v); return *this;}
Fix operator+( const Fix& o ) const {return Fix(v + o.v);}
Fix operator-( const Fix& o ) const {return Fix(v - o.v);}
Fix operator*( const Fix& o ) const {return Fix(mul(v,o.v));}
Fix operator/( const Fix& o ) const {assert(o.v != 0); return Fix(div(v,o.v));}
Fix operator-() const {return Fix(-v);}
bool operator<( const Fix& o ) const {return v<o.v;}
bool operator>( const Fix& o ) const {return v>o.v;}
bool operator<=( const Fix& o ) const {return v<=o.v;}
bool operator>=( const Fix& o ) const {return v>=o.v;}
bool operator!=( const Fix& o ) const {return v!=o.v;}
bool operator==( const Fix& o ) const {return v==o.v;}
Fix abs() const {return v < 0 ? Fix(-v) : *this;}
Fix fraction() const {return Fix( v & ((1<<FIX_SHIFT)-1) );}
int toInt() const {return v>>FIX_SHIFT;}
static Fix atan2( Fix y, Fix x );
//Faster fixed-point multiplication (overflow-risky)
static Fix mulFast( const Fix x, const Fix y )
{
return Fix( Fix_mul( x.v, y.v ) );
}
//Faster fixed-point division (overflow-risky)
static Fix divFast( const Fix x, const Fix y )
{
return Fix( Fix_div( x.v, y.v ) );
}
//Fixed-point multiplication that maintains accuracy and doesn't overflow so easily
static int mul( const int x, const int y )
{
const int a = ( ( 1 << FIX_SHIFT ) - 1 );
const int x_int = x >> FIX_SHIFT;
const int x_frac = x & a;
const int y_int = y >> FIX_SHIFT;
const int y_frac = y & a;
return ( ( x_int * y_int ) << FIX_SHIFT ) +
( x_int * y_frac ) +
( x_frac * y_int ) +
( ( x_frac * y_frac ) >> FIX_SHIFT );
}
//Fixed-point multiplication that maintains accuracy and doesn't overflow
static int div( const int x, const int y )
{
const int one = 1 << FIX_SHIFT;
if ( y == one )
{
// divisor 1
return x;
}
else if ( y > one )
{
// divisor above 1
const int overflowLimit = 1 << ( 31 - FIX_SHIFT );
if ( ( x >= overflowLimit ) || ( x <= -overflowLimit ) )
{
// large dividend: combined division to avoid overflow
const int a = one - 1;
const int x_int_shifted = x & ~a;
const int x_frac = x & a;
return ( ( x_int_shifted / y ) << FIX_SHIFT ) +
( ( x_frac != 0 ) ? ( ( x_frac << FIX_SHIFT ) / y ) : 0 );
}
else
{
// straightforward division
return ( x << FIX_SHIFT ) / y;
}
}
else
{
// divisor below 1
return mul( x, ( one << FIX_SHIFT ) / y );
}
}
// angle as [0,1024]
static Fix sin( int x );
// angle as [0,1024]
static Fix cos( int x );
static Fix sqrt( Fix x );
static int sqrt( int x );
static Fix fromInt( int x ) {return Fix(x<<FIX_SHIFT);}
};
#endif // _FIX_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -