#ifndef _TPFF1616_H
#define _TPFF1616_H

typedef int f1616;

/* Contains code to manipulate fixed point numbers in 16.16 format (i.e. 1 bit
   sign, 15 bit whole part, 16 bit decimal part)
   Addition, subtraction, comparison, etc. are not included here since they can
   be performed as normal */

#ifdef __cplusplus
extern "C" {
#endif

/* Multiply one f1616 by another
   Will round off to +&7FFF.FFFF or -&8000.0000 if an overflow occurs */
extern f1616 f1616_mul(f1616,f1616);

/* Divide one f1616 by another
   Will round off to +&7FFF.FFFF or -&8000.0000 if an overflow occurs (i.e.
   division by zero) */
extern f1616 f1616_div(f1616,f1616);

/* Divide three f1616's by the same number, overwriting the originals
   This routine is faster than doing three divisions seperately
   Will round off to +&7FFF.FFFF or -&8000.0000 if an overflow occurs (i.e.
   division by zero) */
extern void f1616_tridiv(f1616 *,f1616 *,f1616 *,f1616);

/* Calculate the square root of an f1616
   Returns zero if a negative number is passed */
extern f1616 f1616_sqrt(f1616);

/* Calculate the square of a number (i.e. x*x)
   Is a bit faster than f1616_mul(x,x)
   Will round off to +&7FFF.FFFF if an overflow occurs */
extern f1616 f1616_sqr(f1616);

/* Return the sine of an angle (input in degrees)
   360 is the optimal input range; the angle is rounded down to that range by
   a simple subtraction loop and so will be very slow if input is very large */
extern f1616 f1616_sin(f1616);

/* Return the cosine of an angle (input in degrees)
   360 is the optimal input range; the angle is rounded down to that range by
   a simple subtraction loop and so will be very slow if input is very large */
extern f1616 f1616_cos(f1616);

/* Convert an integer to an f1616
   Does not round the output if an overflow occurs */
extern f1616 f1616_FromInt(int i);

/* Convert a float to an f1616
   Will round the output to +&7FFF.FFFF or -&8000.0000 if an overflow occurs */ 
extern f1616 f1616_FromFloat(float f);

/* Convert an f1616 to an int
   Will round the result down (i.e. 0.8 => 0, -0.8 => -1) */
extern int f1616_ToInt(f1616 f);

/* Convert an f1616 to a float */
extern float f1616_ToFloat(f1616 f);

#ifdef __cplusplus
}
#endif

#endif
