home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Headers / g++ / Fix24.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-06  |  13.0 KB  |  599 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /* 
  3. Copyright (C) 1988 Free Software Foundation
  4.     written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
  5.     adapted for libg++ by Doug Lea (dl@rocky.oswego.edu)
  6.  
  7. This file is part of the GNU C++ Library.  This library is free
  8. software; you can redistribute it and/or modify it under the terms of
  9. the GNU Library General Public License as published by the Free
  10. Software Foundation; either version 2 of the License, or (at your
  11. option) any later version.  This library is distributed in the hope
  12. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  13. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  14. PURPOSE.  See the GNU Library General Public License for more details.
  15. You should have received a copy of the GNU Library General Public
  16. License along with this library; if not, write to the Free Software
  17. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. #ifndef _Fix24_h
  21. #ifdef __GNUG__
  22. #pragma interface
  23. #pragma cplusplus
  24. #endif
  25. #define _Fix24_h 1
  26.  
  27. #include <stream.h>
  28. #include <std.h>
  29.  
  30. // extra type definitions 
  31.  
  32. typedef struct {
  33.   long                 u;
  34.   unsigned long           l;
  35. } twolongs;
  36.  
  37. // constant definitions
  38.  
  39. static const int
  40.   Fix24_shift = 31;
  41.           
  42. static const double
  43.   Fix24_fs = 2147483648.,        // 2^Fix24_shift
  44.   Fix24_mult = Fix24_fs,
  45.   Fix24_div = 1./Fix24_fs,
  46.   Fix24_max = 1. - .5/Fix24_fs,
  47.   Fix24_min = -1.;
  48.       
  49. static const unsigned long
  50.   Fix24_msb = 0x80000000L,
  51.   Fix24_lsb = 0x00000100L,
  52.   Fix24_m_max = 0x7fffff00L,
  53.   Fix24_m_min = 0x80000000L;
  54.  
  55. static const double
  56.   Fix48_fs = 36028797018963968.,    // 2^(24+Fix24_shift)
  57.   Fix48_max = 1. - .5/Fix48_fs,
  58.   Fix48_min = -1.,
  59.   Fix48_div_u = 1./Fix24_fs,
  60.   Fix48_div_l = 1./Fix48_fs;
  61.    
  62. static const twolongs
  63.   Fix48_msb = { 0x80000000L, 0L },
  64.   Fix48_lsb = { 0L, 0x00000100L },
  65.   Fix48_m_max = { 0x7fffff00L, 0xffffff00L },
  66.   Fix48_m_min = { 0x80000000L, 0L };
  67.           
  68. //
  69. // Fix24    class: 24-bit Fixed point data type
  70. //
  71. //    consists of a 24-bit mantissa (sign bit & 23 data bits).
  72. //
  73.  
  74. class Fix24 
  75.   friend class          Fix48;
  76.  
  77.   long                  m;
  78.  
  79.   long                  assign(double d);
  80.          operator       double() const;
  81.                         Fix24(long i);
  82.                         Fix24(int i);
  83.  
  84.  
  85. public:
  86.                         Fix24();
  87.                         Fix24(const Fix24&  f);
  88.                         Fix24(double d);
  89.                         Fix24(const Fix48& f);
  90.  
  91.                         ~Fix24();
  92.  
  93.   Fix24&                operator=(const Fix24&  f);
  94.   Fix24&                operator=(double d);
  95.   Fix24&                operator=(const Fix48& f);
  96.  
  97.   friend long&          mantissa(Fix24&  f);
  98.   friend const long&    mantissa(const Fix24&  f);
  99.   friend double         value(const Fix24&  f);
  100.  
  101.   Fix24                 operator +  () const;
  102.   Fix24                 operator -  () const;
  103.  
  104.   friend Fix24          operator +  (const Fix24&  f, const Fix24&  g);
  105.   friend Fix24          operator -  (const Fix24&  f, const Fix24&  g);
  106.   friend Fix48          operator *  (const Fix24&  f, const Fix24&  g);
  107.   friend Fix24          operator *  (const Fix24&  f, int     g);
  108.   friend Fix24          operator *  (int     g, const Fix24&  f);
  109.   friend Fix24          operator /  (const Fix24&  f, const Fix24&  g);
  110.   friend Fix24          operator << (const Fix24&  f, int b);
  111.   friend Fix24          operator >> (const Fix24&  f, int b);
  112.  
  113.   Fix24&                operator += (const Fix24&  f);
  114.   Fix24&                operator -= (const Fix24&  f);
  115.   Fix24&                operator *= (const Fix24&  f);
  116.   Fix24&                operator *= (int     b);
  117.   Fix24&                operator /= (const Fix24&  f);
  118.  
  119.   Fix24&                operator <<=(int b);
  120.   Fix24&                operator >>=(int b);
  121.  
  122.   friend int            operator == (const Fix24&  f, const Fix24&  g);
  123.   friend int            operator != (const Fix24&  f, const Fix24&  g);
  124.   friend int            operator >= (const Fix24&  f, const Fix24&  g);
  125.   friend int            operator <= (const Fix24&  f, const Fix24&  g);
  126.   friend int            operator >  (const Fix24&  f, const Fix24&  g);
  127.   friend int            operator <  (const Fix24&  f, const Fix24&  g);
  128.  
  129.   friend istream&       operator >> (istream& s, Fix24&  f);
  130.   friend ostream&       operator << (ostream& s, const Fix24&  f);
  131.  
  132.   void                  overflow(long&) const;
  133.   void                  range_error(long&) const;
  134. };
  135.  
  136.  
  137. //
  138. // Fix48 class: 48-bit Fixed point data type
  139. //
  140. //    consists of a 48-bit mantissa (sign bit & 47 data bits).
  141. //
  142.  
  143. class Fix48 
  144.   friend class         Fix24;
  145.  
  146.   twolongs             m;
  147.  
  148.   twolongs             assign(double d);
  149.          operator      double() const;
  150.                        Fix48(twolongs i);
  151.  
  152. public:
  153.                        Fix48();
  154.                        Fix48(const Fix48& f);
  155.                        Fix48(const Fix24&  f);
  156.                        Fix48(double d);
  157.                        ~Fix48();
  158.  
  159.   Fix48&               operator =  (const Fix48& f);
  160.   Fix48&               operator =  (const Fix24&  f);
  161.   Fix48&               operator =  (double d);
  162.  
  163.   friend twolongs&     mantissa(Fix48& f);
  164.   friend const twolongs&  mantissa(const Fix48& f);
  165.   friend double        value(const Fix48& f);
  166.  
  167.   Fix48                operator +  () const;
  168.   Fix48                operator -  () const;
  169.  
  170.   friend Fix48         operator +  (const Fix48& f, const Fix48& g);
  171.   friend Fix48         operator -  (const Fix48& f, const Fix48& g);
  172.   friend Fix48         operator *  (const Fix48& f, int    g);
  173.   friend Fix48         operator *  (int    g, const Fix48& f);
  174.   friend Fix48         operator << (const Fix48& f, int b);
  175.   friend Fix48         operator >> (const Fix48& f, int b);
  176.  
  177.   friend Fix48         operator *  (const Fix24&  f, const Fix24&  g);
  178.  
  179.   Fix48&               operator += (const Fix48& f);
  180.   Fix48&               operator -= (const Fix48& f);
  181.   Fix48&               operator *= (int    b);
  182.   Fix48&               operator <<=(int b);
  183.   Fix48&               operator >>=(int b);
  184.  
  185.   friend int           operator == (const Fix48& f, const Fix48& g);
  186.   friend int           operator != (const Fix48& f, const Fix48& g);
  187.   friend int           operator >= (const Fix48& f, const Fix48& g);
  188.   friend int           operator <= (const Fix48& f, const Fix48& g);
  189.   friend int           operator >  (const Fix48& f, const Fix48& g);
  190.   friend int           operator <  (const Fix48& f, const Fix48& g);
  191.  
  192.   friend istream&      operator >> (istream& s, Fix48& f);
  193.   friend ostream&      operator << (ostream& s, const Fix48& f);
  194.  
  195.   void                 overflow(twolongs& i) const;
  196.   void                 range_error(twolongs& i) const;
  197. };
  198.  
  199.  
  200. // active error handler declarations
  201.  
  202. typedef void (*Fix24_peh)(long&);
  203. typedef void (*Fix48_peh)(twolongs&);
  204.  
  205. extern Fix24_peh Fix24_overflow_handler;
  206. extern Fix48_peh Fix48_overflow_handler;
  207.  
  208. extern Fix24_peh Fix24_range_error_handler;
  209. extern Fix48_peh Fix48_range_error_handler;
  210.  
  211.  
  212. // error handler declarations
  213.  
  214. #if defined(SHORT_NAMES) || defined(VMS)
  215. #define    set_overflow_handler    sohndl
  216. #define set_range_error_handler    srnghdl
  217. #endif
  218.  
  219. extern Fix24_peh set_Fix24_overflow_handler(Fix24_peh);
  220. extern Fix48_peh set_Fix48_overflow_handler(Fix48_peh);
  221. extern void set_overflow_handler(Fix24_peh, Fix48_peh);
  222.  
  223. extern Fix24_peh set_Fix24_range_error_handler(Fix24_peh);
  224. extern Fix48_peh set_Fix48_range_error_handler(Fix48_peh);
  225. extern void set_range_error_handler(Fix24_peh, Fix48_peh);
  226.  
  227. extern void
  228.   Fix24_ignore(long&),
  229.   Fix24_overflow_saturate(long&),
  230.   Fix24_overflow_warning_saturate(long&),
  231.   Fix24_warning(long&),
  232.   Fix24_abort(long&);
  233.  
  234. extern void
  235.   Fix48_ignore(twolongs&),
  236.   Fix48_overflow_saturate(twolongs&),
  237.   Fix48_overflow_warning_saturate(twolongs&),
  238.   Fix48_warning(twolongs&),
  239.   Fix48_abort(twolongs&);
  240.  
  241.  
  242. inline Fix24::~Fix24() {}
  243.  
  244. inline Fix24::Fix24(long i)        
  245.   m = i; 
  246. }
  247.  
  248. inline Fix24::Fix24(int i)        
  249.   m = i; 
  250. }
  251.  
  252. inline Fix24::operator double() const
  253.   return  Fix24_div * m; 
  254. }
  255.  
  256. inline Fix24::Fix24()                 
  257.   m = 0; 
  258. }
  259.  
  260. inline Fix24::Fix24(const Fix24&  f)        
  261.   m = f.m; 
  262. }
  263.  
  264. inline Fix24::Fix24(double d)        
  265. {
  266.   m = assign(d);
  267. }
  268.  
  269. inline Fix24::Fix24(const Fix48& f)        
  270.   m = f.m.u;
  271. }
  272.  
  273. inline Fix24&  Fix24::operator=(const Fix24&  f)    
  274.   m = f.m; 
  275.   return *this; 
  276. }
  277.  
  278. inline Fix24&  Fix24::operator=(double d) 
  279.   m = assign(d); 
  280.   return *this; 
  281. }
  282.  
  283. inline Fix24&  Fix24::operator=(const Fix48& f)
  284.   m = f.m.u;
  285.   return *this; 
  286. }
  287.  
  288. inline long& mantissa(Fix24&  f)
  289.   return f.m; 
  290. }
  291.  
  292. inline const long& mantissa(const Fix24&  f)
  293.   return f.m; 
  294. }
  295.  
  296. inline double value(const Fix24&  f)
  297.   return double(f); 
  298. }
  299.  
  300. inline Fix24 Fix24::operator+() const        
  301.   return m; 
  302. }
  303.  
  304. inline Fix24 Fix24::operator-() const
  305.   return -m; 
  306. }
  307.  
  308. inline Fix24 operator+(const Fix24&  f, const Fix24&  g) 
  309. {
  310.   long sum = f.m + g.m;
  311.   if ( (f.m ^ sum) & (g.m ^ sum) & Fix24_msb )
  312.     f.overflow(sum);
  313.   return sum;
  314. }
  315.  
  316. inline Fix24 operator-(const Fix24&  f, const Fix24&  g) 
  317. {
  318.   long sum = f.m - g.m;
  319.   if ( (f.m ^ sum) & (-g.m ^ sum) & Fix24_msb )
  320.     f.overflow(sum);
  321.   return sum;
  322. }
  323.  
  324. inline Fix24 operator*(const Fix24& a, int b)     
  325.   return a.m * b; 
  326. }
  327.  
  328. inline Fix24 operator*(int b, const Fix24& a)     
  329.   return a * b; 
  330. }
  331.  
  332. inline Fix24 operator<<(const Fix24& a, int b)     
  333.   return a.m << b; 
  334. }
  335.  
  336. inline Fix24 operator>>(const Fix24& a, int b)     
  337.   return (a.m >> b) & 0xffffff00L; 
  338. }
  339.  
  340. inline  Fix24&  Fix24:: operator+=(const Fix24&  f)
  341. {
  342.   return *this = *this + f;
  343. }
  344.  
  345. inline Fix24&  Fix24:: operator-=(const Fix24&  f)     
  346.   return *this = *this - f; 
  347. }
  348.  
  349. inline Fix24& Fix24::operator*=(const Fix24& f)     
  350.   return *this = *this * f; 
  351. }
  352.  
  353. inline Fix24&  Fix24:: operator/=(const Fix24&  f)     
  354.   return *this = *this / f; 
  355. }
  356.  
  357. inline Fix24&  Fix24:: operator<<=(int b)    
  358.   return *this = *this << b;
  359. }
  360.  
  361. inline Fix24&  Fix24:: operator>>=(int b)    
  362.   return *this = *this >> b;
  363. }
  364.  
  365. inline Fix24& Fix24::operator*=(int b)
  366.   return *this = *this * b; 
  367. }
  368.  
  369. inline int operator==(const Fix24&  f, const Fix24&  g)    
  370.   return f.m == g.m;
  371. }
  372.  
  373. inline int operator!=(const Fix24&  f, const Fix24&  g)    
  374.   return f.m != g.m;
  375. }
  376.  
  377. inline int operator>=(const Fix24&  f, const Fix24&  g)    
  378.   return f.m >= g.m;
  379. }
  380.  
  381. inline int operator<=(const Fix24&  f, const Fix24&  g)    
  382.   return f.m <= g.m;
  383. }
  384.  
  385. inline int operator>(const Fix24&  f, const Fix24&  g)    
  386.   return f.m > g.m;
  387. }
  388.  
  389. inline int operator<(const Fix24&  f, const Fix24&  g)    
  390.   return f.m < g.m;
  391. }
  392.  
  393. inline istream&  operator>>(istream& s, Fix24&  f)
  394.   double d;
  395.   s >> d; 
  396.   f = d; 
  397.   return s; 
  398. }
  399.  
  400. inline ostream&  operator<<(ostream& s, const Fix24&  f)
  401.   return s << double(f);
  402. }
  403.  
  404. inline Fix48::~Fix48() {}
  405.  
  406. inline Fix48::Fix48(twolongs i)        
  407.   m = i;
  408. }
  409.  
  410. inline Fix48:: operator double() const
  411. /*
  412.  * Note: can't simply do Fix48_div_u * m.u + Fix48_div_l * m.l, because
  413.  * m.u is signed and m.l is unsigned.
  414.  */
  415.   return (m.u >= 0)? Fix48_div_u * m.u + Fix48_div_l * m.l :
  416.       (Fix48_div_u * ((unsigned long)(m.u & 0xffffff00)) 
  417.       + Fix48_div_l * m.l) - 2;
  418. }
  419.  
  420. inline Fix48::Fix48()                
  421.   m.u = 0;
  422.   m.l = 0;
  423. }
  424.  
  425. inline Fix48::Fix48(const Fix48& f)        
  426.   m = f.m;
  427. }
  428.  
  429. inline Fix48::Fix48(const Fix24&  f)    
  430.   m.u = f.m;
  431.   m.l = 0;
  432. }
  433.  
  434. inline Fix48::Fix48(double d)        
  435.   m = assign(d);
  436. }
  437.  
  438. inline Fix48& Fix48::operator=(const Fix48& f)    
  439.   m = f.m;
  440.   return *this; 
  441. }
  442.  
  443. inline Fix48& Fix48::operator=(const Fix24&  f)    
  444.   m.u = f.m;
  445.   m.l = 0;
  446.   return *this;
  447. }
  448.  
  449. inline Fix48& Fix48::operator=(double d)    
  450.   m = assign(d);
  451.   return *this; 
  452. }
  453.  
  454. inline twolongs& mantissa(Fix48& f)    
  455.   return f.m;
  456. }
  457.  
  458. inline const twolongs& mantissa(const Fix48& f)    
  459.   return f.m;
  460. }
  461.  
  462. inline double value(const Fix48& f)
  463.   return double(f);
  464. }
  465.  
  466. inline Fix48 Fix48::operator+() const        
  467.   return m;
  468. }
  469.  
  470. inline Fix48 Fix48::operator-() const
  471.   twolongs n;
  472.   n.l = -m.l;
  473.   n.u = ~m.u + ((n.l ^ m.l) & Fix24_msb ? 0 : Fix24_lsb);
  474.   return Fix48(n);
  475. }
  476.  
  477. inline Fix48 operator*(int b, const Fix48& a)     
  478.   return a * b; 
  479. }
  480.  
  481. inline Fix48& Fix48::operator+=(const Fix48& f)     
  482.   return *this = *this + f;
  483. }
  484.  
  485. inline Fix48& Fix48::operator-=(const Fix48& f)     
  486.   return *this = *this - f;
  487. }
  488.  
  489. inline Fix48& Fix48::operator*=(int b)    
  490.   return *this = *this * b;
  491. }
  492.  
  493. inline Fix48& Fix48::operator<<=(int b)    
  494.   return *this = *this << b;
  495. }
  496.  
  497. inline Fix48& Fix48::operator>>=(int b)    
  498.   return *this = *this >> b;
  499. }
  500.  
  501. inline int operator==(const Fix48& f, const Fix48& g)    
  502.   return f.m.u == g.m.u && f.m.l == g.m.l;
  503. }
  504.  
  505. inline int operator!=(const Fix48& f, const Fix48& g)    
  506.   return f.m.u != g.m.u || f.m.l != g.m.l;
  507. }
  508.  
  509. inline int operator>=(const Fix48& f, const Fix48& g)    
  510.   return f.m.u >= g.m.u || (f.m.u == g.m.u && f.m.l >= g.m.l);
  511. }
  512.  
  513. inline int operator<=(const Fix48& f, const Fix48& g)    
  514.   return f.m.u <= g.m.u || (f.m.u == g.m.u && f.m.l <= g.m.l);
  515. }
  516.  
  517. inline int operator>(const Fix48& f, const Fix48& g)    
  518.   return f.m.u > g.m.u || (f.m.u == g.m.u && f.m.l > g.m.l);
  519. }
  520.  
  521. inline int operator<(const Fix48& f, const Fix48& g)    
  522.   return f.m.u < g.m.u || (f.m.u == g.m.u && f.m.l < g.m.l);
  523. }
  524.  
  525. inline istream& operator>>(istream& s, Fix48& f)
  526.   double d;
  527.   s >> d; 
  528.   f = d; 
  529.   return s; 
  530. }
  531.  
  532. inline ostream& operator<<(ostream& s, const Fix48& f)
  533.   return s << double(f);
  534. }
  535.  
  536. #endif
  537.