/****
 *
 * Copyright (c) 1988 by Sun Microsystems, Inc.
 * @(#)sh_fract.h 22.1 89/08/10 Copyright 1988 Sun Micro
 *
 * FRACT.H - Macros for dealing with fixed point binary numbers.
 * The user does not actually need to know the format of a "fract"
 * as long as one of the following routines are used.  See
 * fr'arch'.il or di/fr'arch'.s for additional details.
 *
 ****/
#ifndef _SH_FRACT

typedef int	fract;

extern	short	fract_overflows;	/* overflow occured flag */

extern	fract	frmul(), frdiv(), frsqrt();
extern	fract	vfradd(), vfrsub(), vfrmul(), vfrdiv();

#define	fradd(x,y)	((x)+(y))
#define	frsub(x,y)	((x)-(y))
#define frrsh(i,n)	((i)>>(n))
#define frlsh(i,n)	((i)<<(n))

#define floorfr(x)	((x)>>16)
#define aafloorfr(x)	((x)>>14)
#define roundfr(x)	(((x)+FRHALF)>>16)
#define ceilingfr(x)	(((x)+fracti(1)-1)>>16)
#define	frfloor(x)	((x)&0xffff0000)
#define	frround(x)	(((x)+FRHALF)&0xffff0000)
#define	frceiling(x)	(((x)+fracti(1)-1)&0xffff0000)

#define fracti(i)	((fract)((i)*(1<<16)))
#define floatfr(x)	(((float) x)/(1<<16))
#define	fractf(x)	(fract) ((x)*(1<<16))

#define FRHUGE		((fract)0x7fffffff)
#define FRSQRT2		((fract)92682)	/* exactly 1.414215087890625 */
#define	FRSQRT2_2	((fract)46341)	/* exactly 0.7071075439453125 */
#define FRPI		((fract)205887)	/* exactly 3.1415863037109375 */
#define FRE		((fract)178142)	/* exactly 2.718281828 */
#define FRHALF		((fract)0x00008000) /* exactly 0.5 */

#define fraction(num, denom) (fracti(num)/(denom))
#define frpercent(pc)	fraction(pc, 100)
#define frsq(x)		frmul(x, x)
#define fractionalbits(x) ((unsigned short) (x))



/* structure for accessing the parts of a fract.
 * POSSIBLE PORTABILITY PROBLEM: WORD ORDER.  These definitions work
 * for both little- and big- endian machines. */

struct FRACT_STRUCT {
#ifdef LITTLEENDIAN
	unsigned short fractional;
	short integer;
#else	/* LITTLEENDIAN */
        short integer;
        unsigned short fractional;
#endif	/* LITTLEENDIAN */
};

/* lfloorfr(x) is equivalent to floorfr(x).  It is only valid for lvalues */
#define lfloorfr(x) ((*(struct FRACT_STRUCT *) &(x)).integer)

#define _SH_FRACT
#endif	/* _SH_FRACT */
