home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / g__lib / fix.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-23  |  9.1 KB  |  449 lines

  1. //
  2. // Fix.h : variable length fixed point data type 
  3. //
  4.  
  5. #ifndef _Fix_h
  6. #pragma once
  7. #define _Fix_h 1
  8.  
  9. #include <stream.h>
  10. #include <std.h>
  11. #include <stddef.h>
  12. #include <Integer.h>
  13.  
  14. typedef unsigned short uint16;
  15. typedef short int16;
  16. typedef unsigned long  uint32;
  17. typedef long int32;
  18.  
  19. #define _Fix_min_length     1
  20. #define _Fix_max_length        65535
  21.  
  22. #define _Fix_min_value        -1.0
  23. #define _Fix_max_value        1.0
  24.  
  25. struct _Frep                    // internal Fix representation
  26. {
  27.   uint16 len;                  // length in bits
  28.   uint16 siz;            // allocated storage
  29.   int16 ref;                  // reference count
  30.   uint16 s[1];            // start of ushort array represention
  31. };
  32.  
  33. typedef struct _Frep* _Fix;
  34.  
  35. extern _Frep _Frep_0;
  36. extern _Frep _Frep_m1;
  37. extern _Frep _Frep_quotient_bump;
  38.  
  39. extern uint16 Fix_default_length;
  40. extern int    Fix_default_print_width;
  41.  
  42. class Fix
  43. {
  44.   _Fix            rep;
  45.  
  46.           Fix(_Fix);
  47.  
  48.   void          unique();
  49.  
  50. public:
  51.           Fix();
  52.                   Fix(Fix&);
  53.           Fix(double&);
  54.                   Fix(int);
  55.                   Fix(int, Fix&);
  56.                   Fix(int, double&);
  57.  
  58.                   ~Fix();
  59.  
  60.   Fix             operator =  (Fix&);
  61.   Fix             operator =  (double&);
  62.  
  63.   friend int      operator == (Fix&, Fix& );
  64.   friend int      operator != (Fix&, Fix&);
  65.  
  66.   friend int      operator <  (Fix&, Fix&);
  67.   friend int      operator <= (Fix&, Fix&);
  68.   friend int      operator >  (Fix&, Fix&);
  69.   friend int      operator >= (Fix&, Fix&);
  70.  
  71.   Fix&            operator +  ();
  72.   Fix             operator -  ();
  73.  
  74.   friend Fix      operator +  (Fix&, Fix&);
  75.   friend Fix      operator -  (Fix&, Fix&);
  76.   friend Fix      operator *  (Fix&, Fix&);
  77.   friend Fix      operator /  (Fix&, Fix&);
  78.  
  79.   friend Fix      operator *  (Fix&, int);
  80.   friend Fix      operator *  (int, Fix&);
  81.   friend Fix      operator %  (Fix&, int);
  82.   friend Fix      operator << (Fix&, int);
  83.   friend Fix      operator >> (Fix&, int);
  84.  
  85.   friend Fix     operator <? (Fix&, Fix&); // min
  86.   friend Fix     operator >? (Fix&, Fix&); // max
  87.  
  88.   Fix            operator += (Fix&);
  89.   Fix            operator -= (Fix&);
  90.   Fix            operator *= (Fix&);
  91.   Fix            operator /= (Fix&);
  92.  
  93.   Fix            operator *= (int);
  94.   Fix            operator %= (int);
  95.   Fix            operator <<=(int);
  96.   Fix            operator >>=(int);
  97.  
  98.   friend char*    Ftoa(Fix&, int width = Fix_default_print_width);
  99.   friend Fix      atoF(const char*, int len = Fix_default_length);
  100.   
  101.   friend istream& operator >> (istream&, Fix&);
  102.   friend ostream& operator << (ostream&, Fix&);
  103.  
  104.   // built-in functions
  105.   friend Fix      abs(Fix);        // absolute value
  106.   friend int      sgn(Fix&);        // -1, 0, +1
  107.   friend Integer  mantissa(Fix&);    // integer representation
  108.   friend double   value(Fix&);        // double value
  109.   friend int      length(Fix&);        // field length
  110.   friend void      show(Fix&);        // show contents
  111.  
  112.   // error handlers
  113.   void            error(char* msg);        // error handler
  114.   void            range_error(char* msg);    // range error handler
  115.  
  116.   // internal class functions
  117.   friend void      mask(_Fix);
  118.   friend int      compare(_Fix, _Fix = &_Frep_0);
  119.  
  120.   friend _Fix      new_Fix(uint16);
  121.   friend _Fix      new_Fix(uint16, _Fix);
  122.   friend _Fix      new_Fix(uint16, double);
  123.  
  124.   friend _Fix      copy(_Fix, _Fix);
  125.   friend _Fix      negate(_Fix, _Fix = NULL);
  126.   friend _Fix      add(_Fix, _Fix, _Fix = NULL);
  127.   friend _Fix      subtract(_Fix, _Fix, _Fix = NULL);
  128.   friend _Fix      multiply(_Fix, _Fix, _Fix = NULL);
  129.   friend _Fix      multiply(_Fix, int, _Fix = NULL);
  130.   friend _Fix      divide(_Fix, _Fix, _Fix = NULL, _Fix = NULL);
  131.   friend _Fix      shift(_Fix, int, _Fix = NULL);
  132.  
  133.   // non-operator versions for user
  134.   friend void      negate(Fix& x, Fix& r);
  135.   friend void      add(Fix& x, Fix& y, Fix& r);
  136.   friend void      subtract(Fix& x, Fix& y, Fix& r);
  137.   friend void      multiply(Fix& x, Fix& y, Fix& r);
  138.   friend void      divide(Fix& x, Fix& y, Fix& q, Fix& r);
  139.   friend void      shift(Fix& x, int y, Fix& r);
  140. };
  141.  
  142. // error handlers
  143.  
  144. extern void    
  145.   default_Fix_error_handler(char*),
  146.   default_Fix_range_error_handler(char*);
  147.  
  148. extern one_arg_error_handler_t 
  149.   Fix_error_handler,
  150.   Fix_range_error_handler;
  151.  
  152. extern one_arg_error_handler_t 
  153.   set_Fix_error_handler(one_arg_error_handler_t f),
  154.   set_Fix_range_error_handler(one_arg_error_handler_t f);
  155.  
  156. typedef void (*Fix_peh)(_Fix&);
  157. extern Fix_peh Fix_overflow_handler;
  158.  
  159. extern void 
  160.   Fix_overflow_saturate(_Fix&),
  161.   Fix_overflow_wrap(_Fix&),
  162.   Fix_overflow_warning_saturate(_Fix&),
  163.   Fix_overflow_warning(_Fix&),
  164.   Fix_overflow_error(_Fix&);
  165.  
  166. extern Fix_peh set_overflow_handler(Fix_peh);
  167.  
  168. extern int Fix_set_default_length(int);
  169.  
  170. // function definitions
  171.  
  172. inline void Fix::unique()
  173. {
  174.   if ( rep->ref > 1 )
  175.   {
  176.     rep->ref--;
  177.     rep = new_Fix(rep->len,rep);
  178.   }
  179. }
  180.  
  181. inline void mask (_Fix x)
  182. {
  183.   int n = x->len & 0x0f;
  184.   if ( n )
  185.     x->s[x->siz - 1] &= 0xffff0000 >> n; 
  186. }
  187.  
  188. inline _Fix copy(_Fix from, _Fix to)
  189. {
  190.   uint16 *ts = to->s, *fs = from->s;
  191.   int ilim = to->siz < from->siz ? to->siz : from->siz;
  192.   for ( int i=0; i < ilim; i++ )
  193.     *ts++ = *fs++;
  194.   for ( ; i < to->siz; i++ )
  195.     *ts++ = 0;
  196.   mask(to);
  197.   return to;
  198. }
  199.  
  200. inline Fix::Fix(_Fix f)
  201. {
  202.   rep = f;
  203. }
  204.  
  205. inline Fix::Fix()
  206. {
  207.   rep = new_Fix(Fix_default_length);
  208. }
  209.  
  210. inline Fix::Fix(int len)
  211. {
  212.   if ( len < _Fix_min_length || len > _Fix_max_length )
  213.     error("illegal length in declaration");
  214.   rep = new_Fix((uint16 )len);
  215. }
  216.  
  217. inline Fix::Fix(double& d)
  218. {
  219.   rep = new_Fix(Fix_default_length,d);
  220. }
  221.  
  222. inline Fix::Fix(Fix&  y)
  223. {
  224.   rep = y.rep, rep->ref++;
  225. }
  226.  
  227. inline Fix::Fix(int len, Fix&  y)
  228. {
  229.   if ( len < _Fix_min_length || len > _Fix_max_length )
  230.     error("illegal length in declaration");
  231.   rep = new_Fix((uint16 )len,y.rep);
  232. }
  233.  
  234. inline Fix::Fix(int len, double& d)
  235. {
  236.   if ( len < _Fix_min_length || len > _Fix_max_length )
  237.     error("illegal length in declaration");
  238.   rep = new_Fix((uint16 )len,d);
  239. }
  240.  
  241. inline Fix::~Fix()
  242. {
  243.   if ( --rep->ref <= 0 ) delete rep;
  244. }
  245.  
  246. inline Fix  Fix::operator = (Fix&  y)
  247. {
  248.   if ( rep->len == y.rep->len ) {
  249.     if ( --rep->ref <= 0 ) delete rep;
  250.     rep = y.rep, rep->ref++;
  251.   }
  252.   else {
  253.     unique();
  254.     copy(y.rep,rep);
  255.   }
  256.   return *this;
  257. }
  258.  
  259. inline Fix  Fix::operator = (double& d)
  260. {
  261.   if ( --rep->ref <= 0 ) delete rep;
  262.   rep = new_Fix(rep->len,d);
  263.   return *this;
  264. }
  265.  
  266. inline int operator == (Fix&  x, Fix&  y)
  267. {
  268.   return compare(x.rep, y.rep) == 0; 
  269. }
  270.  
  271. inline int operator != (Fix&  x, Fix&  y)
  272. {
  273.   return compare(x.rep, y.rep) != 0; 
  274. }
  275.  
  276. inline int operator <  (Fix&  x, Fix&  y)
  277. {
  278.   return compare(x.rep, y.rep) <  0; 
  279. }
  280.  
  281. inline int operator <= (Fix&  x, Fix&  y)
  282. {
  283.   return compare(x.rep, y.rep) <= 0; 
  284. }
  285.  
  286. inline int operator >  (Fix&  x, Fix&  y)
  287. {
  288.   return compare(x.rep, y.rep) >  0; 
  289. }
  290.  
  291. inline int operator >= (Fix&  x, Fix&  y)
  292. {
  293.   return compare(x.rep, y.rep) >= 0; 
  294. }
  295.  
  296. inline Fix& Fix::operator +  ()
  297. {
  298.   return *this;
  299. }
  300.  
  301. inline Fix Fix::operator -  ()
  302. {
  303.   _Fix r = negate(rep); return r;
  304. }
  305.  
  306. inline Fix      operator +  (Fix&  x, Fix& y)
  307. {
  308.   _Fix r = add(x.rep, y.rep); return r;
  309. }
  310.  
  311. inline Fix      operator -  (Fix&  x, Fix& y)
  312. {
  313.   _Fix r = subtract(x.rep, y.rep); return r;
  314. }
  315.  
  316. inline Fix      operator *  (Fix&  x, Fix& y)
  317. {
  318.   _Fix r = multiply(x.rep, y.rep); return r;
  319. }
  320.  
  321. inline Fix      operator *  (Fix&  x, int y)
  322. {
  323.   _Fix r = multiply(x.rep, y); return r;
  324. }
  325.  
  326. inline Fix      operator *  (int  y, Fix& x)
  327. {
  328.   _Fix r = multiply(x.rep, y); return r;
  329. }
  330.  
  331. inline Fix operator / (Fix& x, Fix& y)
  332. {
  333.   _Fix r = divide(x.rep, y.rep); return r;
  334. }
  335.  
  336. inline Fix  Fix::operator += (Fix& y)
  337. {
  338.   unique(); add(rep, y.rep, rep); return *this;
  339. }
  340.  
  341. inline Fix  Fix::operator -= (Fix& y)
  342. {
  343.   unique(); subtract(rep, y.rep, rep); return *this;
  344. }
  345.  
  346. inline Fix  Fix::operator *= (Fix& y)
  347. {
  348.   unique(); multiply(rep, y.rep, rep); return *this;
  349. }
  350.  
  351. inline Fix  Fix::operator *= (int y)
  352. {
  353.   unique(); multiply(rep, y, rep); return *this;
  354. }
  355.  
  356. inline Fix Fix::operator /= (Fix& y)
  357. {
  358.   unique(); divide(rep, y.rep, rep); return *this;
  359. }
  360.  
  361. inline Fix operator % (Fix& x, int y)
  362. {
  363.   Fix r((int )x.rep->len + y, x); return r;
  364. }
  365.  
  366. inline Fix      operator << (Fix&  x, int y)
  367. {
  368.   _Fix rep = shift(x.rep, y); return rep;
  369. }
  370.  
  371. inline Fix      operator >> (Fix&  x, int y)
  372. {  
  373.   _Fix rep = shift(x.rep, -y); return rep;
  374. }
  375.  
  376. inline Fix Fix::operator <<= (int y)
  377. {
  378.   unique(); shift(rep, y, rep); return *this;
  379. }
  380.  
  381. inline Fix  Fix::operator >>= (int y)
  382. {
  383.   unique(); shift(rep, -y, rep); return *this;
  384. }
  385.  
  386. inline Fix operator <? (Fix& x, Fix& y)
  387. {
  388.   if ( compare(x.rep, y.rep) <= 0 ) return x; else return y;
  389. }
  390.  
  391. inline Fix operator >? (Fix& x, Fix& y)
  392. {
  393.   if ( compare(x.rep, y.rep) >= 0 ) return x; else return y;
  394. }
  395.  
  396. inline Fix abs(Fix  x)
  397. {
  398.   _Fix r = (compare(x.rep) >= 0 ? x.rep : negate(x.rep));
  399.   return r;
  400. }
  401.  
  402. inline int sgn(Fix& x)
  403. {
  404.   int a = compare(x.rep);
  405.   return a == 0 ? 0 : (a > 0 ? 1 : -1);
  406. }
  407.  
  408. inline int length(Fix& x)
  409. {
  410.   return x.rep->len;
  411. }
  412.  
  413. inline ostream& operator << (ostream& s, Fix& y)
  414. {
  415.   return s << Ftoa(y);
  416. }
  417.  
  418. inline void    negate (Fix& x, Fix& r)
  419. {
  420.   negate(x.rep, r.rep);
  421. }
  422.  
  423. inline void    add (Fix& x, Fix& y, Fix& r)
  424. {
  425.   add(x.rep, y.rep, r.rep);
  426. }
  427.  
  428. inline void    subtract (Fix& x, Fix& y, Fix& r)
  429. {
  430.   subtract(x.rep, y.rep, r.rep);
  431. }
  432.  
  433. inline void    multiply (Fix& x, Fix& y, Fix& r)
  434. {
  435.   multiply(x.rep, y.rep, r.rep);
  436. }
  437.  
  438. inline void    divide (Fix& x, Fix& y, Fix& q, Fix& r)
  439. {
  440.   divide(x.rep, y.rep, q.rep, r.rep);
  441. }
  442.  
  443. inline void    shift (Fix& x, int y, Fix& r)
  444. {
  445.   shift(x.rep, y, r.rep);
  446. }
  447.  
  448. #endif
  449.