libtonc
Base math

Basic math macros and functions like MIN, MAX. More...

Modules

 Fixed point math
 

core math macros

INLINE int sgn (int x)
 Get the sign of x.
 
INLINE int sgn3 (int x)
 Tri-state sign of x: -1 for negative, 0 for 0, +1 for positive.
 
INLINE int max (int a, int b)
 Get the maximum of a and b.
 
INLINE int min (int a, int b)
 Get the minimum of a and b.
 
#define ABS(x)   ( (x)>=0 ? (x) : -(x) )
 Get the absolute value of x.
 
#define SGN(x)   ( (x)>=0 ? 1 : -1 )
 Get the sign of x.
 
#define SGN2   SGN
 Get the absolute value of x.
 
#define SGN3(x)   ( (x)>0 ? 1 : ( (x)<0 ? -1 : 0) )
 Tri-state sign: -1 for negative, 0 for 0, +1 for positive.
 
#define MAX(a, b)   ( ((a) > (b)) ? (a) : (b) )
 Get the maximum of a and b.
 
#define MIN(a, b)   ( ((a) < (b)) ? (a) : (b) )
 Get the minimum of a and b.
 
#define SWAP2(a, b)   do { a=(a)-(b); b=(a)+(b); a=(b)-(a); } while(0)
 In-place swap.
 
#define SWAP   SWAP2
 Get the absolute value of x.
 
#define SWAP3(a, b, tmp)   do { (tmp)=(a); (a)=(b); (b)=(tmp); } while(0)
 Swaps a and b, using tmp as a temporary.
 

Boundary response macros

INLINE BOOL in_range (int x, int min, int max)
 Range check.
 
INLINE int clamp (int x, int min, int max)
 Truncates x to stay in range [min, max>
 
INLINE int reflect (int x, int min, int max)
 Reflects x at boundaries min and max.
 
INLINE int wrap (int x, int min, int max)
 Wraps x to stay in range [min, max>
 
INLINE FIXED int2fx (int d)
 Convert an integer to fixed-point.
 
INLINE FIXED float2fx (float f)
 Convert a float to fixed-point.
 
INLINE u32 fx2uint (FIXED fx)
 Convert a FIXED point value to an unsigned integer (orly?).
 
INLINE u32 fx2ufrac (FIXED fx)
 Get the unsigned fractional part of a fixed point value (orly?).
 
INLINE int fx2int (FIXED fx)
 Convert a FIXED point value to an signed integer.
 
INLINE float fx2float (FIXED fx)
 Convert a fixed point value to floating point.
 
INLINE FIXED fxadd (FIXED fa, FIXED fb)
 Add two fixed point values.
 
INLINE FIXED fxsub (FIXED fa, FIXED fb)
 Subtract two fixed point values.
 
INLINE FIXED fxmul (FIXED fa, FIXED fb)
 Multiply two fixed point values.
 
INLINE FIXED fxdiv (FIXED fa, FIXED fb)
 Divide two fixed point values.
 
INLINE FIXED fxmul64 (FIXED fa, FIXED fb)
 Multiply two fixed point values using 64bit math.
 
INLINE FIXED fxdiv64 (FIXED fa, FIXED fb)
 Divide two fixed point values using 64bit math.
 
#define IN_RANGE(x, min, max)   ( ((x)>=(min)) && ((x)<(max)) )
 Range check.
 
#define CLAMP(x, min, max)    ( (x)>=(max) ? ((max)-1) : ( ((x)<(min)) ? (min) : (x) ) )
 Truncates x to stay in range [min, max>
 
#define REFLECT(x, min, max)    ( (x)>=(max) ? 2*((max)-1)-(x) : ( ((x)<(min)) ? 2*(min)-(x) : (x) ) )
 Reflects x at boundaries min and max.
 
#define WRAP(x, min, max)    ( (x)>=(max) ? (x)+(min)-(max) : ( ((x)<(min)) ? (x)+(max)-(min) : (x) ) )
 Wraps x to stay in range [min, max>
 
#define FIX_SHIFT   8
 Range check.
 
#define FIX_SCALE   ( 1<<FIX_SHIFT )
 Range check.
 
#define FIX_MASK   ( FIX_SCALE-1 )
 Range check.
 
#define FIX_SCALEF   ( (float)FIX_SCALE )
 Range check.
 
#define FIX_SCALEF_INV   ( 1.0/FIX_SCALEF )
 Range check.
 
#define FIX_ONE   FIX_SCALE
 Range check.
 
#define FX_RECIPROCAL(a, fp)   ( ((1<<(fp))+(a)-1)/(a) )
 Get the fixed point reciprocal of a, in fp fractional bits.
 
#define FX_RECIMUL(x, a, fp)   ( ((x)*((1<<(fp))+(a)-1)/(a))>>(fp) )
 Perform the division x/ a by reciprocal multiplication.
 

Detailed Description

Basic math macros and functions like MIN, MAX.

Macro Definition Documentation

◆ CLAMP

#define CLAMP (   x,
  min,
  max 
)     ( (x)>=(max) ? ((max)-1) : ( ((x)<(min)) ? (min) : (x) ) )

Truncates x to stay in range [min, max>

Returns
Truncated value of x.
Note
max is exclusive!

◆ FX_RECIMUL

#define FX_RECIMUL (   x,
  a,
  fp 
)    ( ((x)*((1<<(fp))+(a)-1)/(a))>>(fp) )

Perform the division x/ a by reciprocal multiplication.

Division is slow, but you can approximate division by a constant by multiplying with its reciprocal: x/a vs x*(1/a). This routine gives the reciprocal of a as a fixed point number with fp fractional bits.

Parameters
aValue to take the reciprocal of.
fpNumber of fixed point bits
Note
The routine does do a division, but the compiler will optimize it to a single constant ... if both a and fp are constants!
Rules for safe reciprocal division, using n = 2fp and m = (n+a-1)/a (i.e., rounding up)
  • Maximum safe numerator x: x < n/(m*a-n)
  • Minimum n for known x: n > x*(a-1)

◆ FX_RECIPROCAL

#define FX_RECIPROCAL (   a,
  fp 
)    ( ((1<<(fp))+(a)-1)/(a) )

Get the fixed point reciprocal of a, in fp fractional bits.

Parameters
aValue to take the reciprocal of.
fpNumber of fixed point bits
Note
The routine does do a division, but the compiler will optimize it to a single constant ... if both a and fp are constants!
See also
FX_RECIMUL

◆ REFLECT

#define REFLECT (   x,
  min,
  max 
)     ( (x)>=(max) ? 2*((max)-1)-(x) : ( ((x)<(min)) ? 2*(min)-(x) : (x) ) )

Reflects x at boundaries min and max.

If x is outside the range [min, max>, it'll be placed inside again with the same distance to the 'wall', but on the other side. Example for lower border: y = min - (x- min) = 2*min + x.

Returns
Reflected value of x.
Note
max is exclusive!

Function Documentation

◆ clamp()

INLINE int clamp ( int  x,
int  min,
int  max 
)

Truncates x to stay in range [min, max>

Returns
Truncated value of x.
Note
max is exclusive!

References max(), and min().

◆ reflect()

INLINE int reflect ( int  x,
int  min,
int  max 
)

Reflects x at boundaries min and max.

If x is outside the range [min, max>, it'll be placed inside again with the same distance to the 'wall', but on the other side. Example for lower border: y = min - (x- min) = 2*min + x.

Returns
Reflected value of x.
Note
max is exclusive!

References max(), and min().