home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / g__inc / xfix24.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-23  |  12.1 KB  |  591 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 once
  23. #pragma interface
  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();
  81.                         Fix24(long i);
  82.                         Fix24(int i);
  83.  
  84.  
  85. public:
  86.                         Fix24();
  87.                         Fix24(Fix24&  f);
  88.                         Fix24(double d);
  89.                         Fix24(Fix48& f);
  90.  
  91.                         ~Fix24();
  92.  
  93.   Fix24&                operator=(Fix24&  f);
  94.   Fix24&                operator=(double d);
  95.   Fix24&                operator=(Fix48& f);
  96.  
  97.   friend long&          mantissa(Fix24&  f);
  98.   friend double         value(Fix24&  f);
  99.  
  100.   Fix24                 operator +  ();
  101.   Fix24                 operator -  ();
  102.  
  103.   friend Fix24          operator +  (Fix24&  f, Fix24&  g);
  104.   friend Fix24          operator -  (Fix24&  f, Fix24&  g);
  105.   friend Fix48          operator *  (Fix24&  f, Fix24&  g);
  106.   friend Fix24          operator *  (Fix24&  f, long     g);
  107.   friend Fix24          operator *  (long     g, Fix24&  f);
  108.   friend Fix24          operator /  (Fix24&  f, Fix24&  g);
  109.   friend Fix24          operator << (Fix24&  f, int b);
  110.   friend Fix24          operator >> (Fix24&  f, int b);
  111.  
  112.   Fix24&                operator += (Fix24&  f);
  113.   Fix24&                operator -= (Fix24&  f);
  114.   Fix24&                operator *= (Fix24&  f);
  115.   Fix24&                operator *= (long    b);
  116.   Fix24&                operator /= (Fix24&  f);
  117.  
  118.   Fix24&                operator <<=(int b);
  119.   Fix24&                operator >>=(int b);
  120.  
  121.   friend int            operator == (Fix24&  f, Fix24&  g);
  122.   friend int            operator != (Fix24&  f, Fix24&  g);
  123.   friend int            operator >= (Fix24&  f, Fix24&  g);
  124.   friend int            operator <= (Fix24&  f, Fix24&  g);
  125.   friend int            operator >  (Fix24&  f, Fix24&  g);
  126.   friend int            operator <  (Fix24&  f, Fix24&  g);
  127.  
  128.   friend istream&       operator >> (istream& s, Fix24&  f);
  129.   friend ostream&       operator << (ostream& s, Fix24&  f);
  130.  
  131.   void                  overflow(long&);
  132.   void                  range_error(long&);
  133. };
  134.  
  135.  
  136. //
  137. // Fix48 class: 48-bit Fixed point data type
  138. //
  139. //    consists of a 48-bit mantissa (sign bit & 47 data bits).
  140. //
  141.  
  142. class Fix48 
  143.   friend class         Fix24;
  144.  
  145.   twolongs             m;
  146.  
  147.   twolongs             assign(double d);
  148.          operator      double();
  149.                        Fix48(twolongs i);
  150.  
  151. public:
  152.                        Fix48();
  153.                        Fix48(Fix48& f);
  154.                        Fix48(Fix24&  f);
  155.                        Fix48(double d);
  156.                        ~Fix48();
  157.  
  158.   Fix48&               operator =  (Fix48& f);
  159.   Fix48&               operator =  (Fix24&  f);
  160.   Fix48&               operator =  (double d);
  161.  
  162.   friend twolongs&     mantissa(Fix48& f);
  163.   friend double        value(Fix48& f);
  164.  
  165.   Fix48                operator +  ();
  166.   Fix48                operator -  ();
  167.  
  168.   friend Fix48         operator +  (Fix48& f, Fix48& g);
  169.   friend Fix48         operator -  (Fix48& f, Fix48& g);
  170.   friend Fix48         operator *  (Fix48& f, long   g);
  171.   friend Fix48         operator *  (long   g, Fix48& f);
  172.   friend Fix48         operator << (Fix48& f, int b);
  173.   friend Fix48         operator >> (Fix48& f, int b);
  174.  
  175.   friend Fix48         operator *  (Fix24&  f, Fix24&  g);
  176.  
  177.   Fix48&               operator += (Fix48& f);
  178.   Fix48&               operator -= (Fix48& f);
  179.   Fix48&               operator *= (long   b);
  180.   Fix48&               operator <<=(int b);
  181.   Fix48&               operator >>=(int b);
  182.  
  183.   friend int           operator == (Fix48& f, Fix48& g);
  184.   friend int           operator != (Fix48& f, Fix48& g);
  185.   friend int           operator >= (Fix48& f, Fix48& g);
  186.   friend int           operator <= (Fix48& f, Fix48& g);
  187.   friend int           operator >  (Fix48& f, Fix48& g);
  188.   friend int           operator <  (Fix48& f, Fix48& g);
  189.  
  190.   friend istream&      operator >> (istream& s, Fix48& f);
  191.   friend ostream&      operator << (ostream& s, Fix48& f);
  192.  
  193.   void                 overflow(twolongs& i);
  194.   void                 range_error(twolongs& i);
  195. };
  196.  
  197.  
  198. // active error handler declarations
  199.  
  200. typedef void (*Fix24_peh)(long&);
  201. typedef void (*Fix48_peh)(twolongs&);
  202.  
  203. extern Fix24_peh Fix24_overflow_handler;
  204. extern Fix48_peh Fix48_overflow_handler;
  205.  
  206. extern Fix24_peh Fix24_range_error_handler;
  207. extern Fix48_peh Fix48_range_error_handler;
  208.  
  209.  
  210. // error handler declarations
  211.  
  212. #if defined(SHORT_NAMES) || defined(VMS)
  213. #define    set_overflow_handler    sohndl
  214. #define set_range_error_handler    srnghdl
  215. #endif
  216.  
  217. extern Fix24_peh set_Fix24_overflow_handler(Fix24_peh);
  218. extern Fix48_peh set_Fix48_overflow_handler(Fix48_peh);
  219. extern void set_overflow_handler(Fix24_peh, Fix48_peh);
  220.  
  221. extern Fix24_peh set_Fix24_range_error_handler(Fix24_peh);
  222. extern Fix48_peh set_Fix48_range_error_handler(Fix48_peh);
  223. extern void set_range_error_handler(Fix24_peh, Fix48_peh);
  224.  
  225. extern void
  226.   Fix24_ignore(long&),
  227.   Fix24_overflow_saturate(long&),
  228.   Fix24_overflow_warning_saturate(long&),
  229.   Fix24_warning(long&),
  230.   Fix24_abort(long&);
  231.  
  232. extern void
  233.   Fix48_ignore(twolongs&),
  234.   Fix48_overflow_saturate(twolongs&),
  235.   Fix48_overflow_warning_saturate(twolongs&),
  236.   Fix48_warning(twolongs&),
  237.   Fix48_abort(twolongs&);
  238.  
  239. #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
  240.  
  241. inline Fix24::~Fix24() {}
  242.  
  243. inline Fix24::Fix24(long i)        
  244.   m = i; 
  245. }
  246.  
  247. inline Fix24::Fix24(int i)        
  248.   m = i; 
  249. }
  250.  
  251. inline Fix24::operator double() 
  252.   return  Fix24_div * m; 
  253. }
  254.  
  255. inline Fix24::Fix24()                 
  256.   m = 0; 
  257. }
  258.  
  259. inline Fix24::Fix24(Fix24&  f)        
  260.   m = f.m; 
  261. }
  262.  
  263. inline Fix24::Fix24(double d)        
  264. {
  265.   m = assign(d);
  266. }
  267.  
  268. inline Fix24::Fix24(Fix48& f)        
  269.   m = f.m.u;
  270. }
  271.  
  272. inline Fix24&  Fix24::operator=(Fix24&  f)    
  273.   m = f.m; 
  274.   return *this; 
  275. }
  276.  
  277. inline Fix24&  Fix24::operator=(double d) 
  278.   m = assign(d); 
  279.   return *this; 
  280. }
  281.  
  282. inline Fix24&  Fix24::operator=(Fix48& f)
  283.   m = f.m.u;
  284.   return *this; 
  285. }
  286.  
  287. inline long& mantissa(Fix24&  f)    
  288.   return f.m; 
  289. }
  290.  
  291. inline double value(Fix24&  f)        
  292.   return double(f); 
  293. }
  294.  
  295. inline Fix24 Fix24::operator+()         
  296.   return m; 
  297. }
  298.  
  299. inline Fix24 Fix24::operator-()         
  300.   return -m; 
  301. }
  302.  
  303. inline Fix24 operator+(Fix24&  f, Fix24&  g) 
  304. {
  305.   long sum = f.m + g.m;
  306.   if ( (f.m ^ sum) & (g.m ^ sum) & Fix24_msb )
  307.     f.overflow(sum);
  308.   return sum;
  309. }
  310.  
  311. inline Fix24 operator-(Fix24&  f, Fix24&  g) 
  312. {
  313.   long sum = f.m - g.m;
  314.   if ( (f.m ^ sum) & (-g.m ^ sum) & Fix24_msb )
  315.     f.overflow(sum);
  316.   return sum;
  317. }
  318.  
  319. inline Fix24 operator*(Fix24& a, long b)     
  320.   return a.m * b; 
  321. }
  322.  
  323. inline Fix24 operator*(long b, Fix24& a)     
  324.   return a * b; 
  325. }
  326.  
  327. inline Fix24 operator<<(Fix24& a, int b)     
  328.   return a.m << b; 
  329. }
  330.  
  331. inline Fix24 operator>>(Fix24& a, int b)     
  332.   return (a.m >> b) & 0xffffff00L; 
  333. }
  334.  
  335. inline  Fix24&  Fix24:: operator+=(Fix24&  f)
  336.   return *this = *this + f; 
  337. }
  338.  
  339. inline Fix24&  Fix24:: operator-=(Fix24&  f)     
  340.   return *this = *this - f; 
  341. }
  342.  
  343. inline Fix24& Fix24::operator*=(Fix24& f)     
  344.   return *this = *this * f; 
  345. }
  346.  
  347. inline Fix24&  Fix24:: operator/=(Fix24&  f)     
  348.   return *this = *this / f; 
  349. }
  350.  
  351. inline Fix24&  Fix24:: operator<<=(int b)    
  352.   return *this = *this << b;
  353. }
  354.  
  355. inline Fix24&  Fix24:: operator>>=(int b)    
  356.   return *this = *this >> b;
  357. }
  358.  
  359. inline Fix24& Fix24::operator*=(long b)
  360.   return *this = *this * b; 
  361. }
  362.  
  363. inline int operator==(Fix24&  f, Fix24&  g)    
  364.   return f.m == g.m;
  365. }
  366.  
  367. inline int operator!=(Fix24&  f, Fix24&  g)    
  368.   return f.m != g.m;
  369. }
  370.  
  371. inline int operator>=(Fix24&  f, Fix24&  g)    
  372.   return f.m >= g.m;
  373. }
  374.  
  375. inline int operator<=(Fix24&  f, Fix24&  g)    
  376.   return f.m <= g.m;
  377. }
  378.  
  379. inline int operator>(Fix24&  f, Fix24&  g)    
  380.   return f.m > g.m;
  381. }
  382.  
  383. inline int operator<(Fix24&  f, Fix24&  g)    
  384.   return f.m < g.m;
  385. }
  386.  
  387. inline istream&  operator>>(istream& s, Fix24&  f)
  388.   double d;
  389.   s >> d; 
  390.   f = d; 
  391.   return s; 
  392. }
  393.  
  394. inline ostream&  operator<<(ostream& s, Fix24&  f)
  395.   return s << double(f);
  396. }
  397.  
  398. inline Fix48::~Fix48() {}
  399.  
  400. inline Fix48::Fix48(twolongs i)        
  401.   m = i;
  402. }
  403.  
  404. inline Fix48:: operator double()        
  405. /*
  406.  * Note: can't simply do Fix48_div_u * m.u + Fix48_div_l * m.l, because
  407.  * m.u is signed and m.l is unsigned.
  408.  */
  409.   return (m.u >= 0)? Fix48_div_u * m.u + Fix48_div_l * m.l :
  410.       (Fix48_div_u * ((unsigned long)(m.u & 0xffffff00)) 
  411.       + Fix48_div_l * m.l) - 2;
  412. }
  413.  
  414. inline Fix48::Fix48()                
  415.   m.u = 0;
  416.   m.l = 0;
  417. }
  418.  
  419. inline Fix48::Fix48(Fix48& f)        
  420.   m = f.m;
  421. }
  422.  
  423. inline Fix48::Fix48(Fix24&  f)    
  424.   m.u = f.m;
  425.   m.l = 0;
  426. }
  427.  
  428. inline Fix48::Fix48(double d)        
  429.   m = assign(d);
  430. }
  431.  
  432. inline Fix48& Fix48::operator=(Fix48& f)    
  433.   m = f.m;
  434.   return *this; 
  435. }
  436.  
  437. inline Fix48& Fix48::operator=(Fix24&  f)    
  438.   m.u = f.m;
  439.   m.l = 0;
  440.   return *this;
  441. }
  442.  
  443. inline Fix48& Fix48::operator=(double d)    
  444.   m = assign(d);
  445.   return *this; 
  446. }
  447.  
  448. inline twolongs& mantissa(Fix48& f)    
  449.   return f.m;
  450. }
  451.  
  452. inline double value(Fix48& f)        
  453.   return double(f);
  454. }
  455.  
  456. inline Fix48 Fix48::operator+()         
  457.   return m;
  458. }
  459.  
  460. inline Fix48 Fix48::operator-()         
  461.   twolongs n;
  462.   n.l = -m.l;
  463.   n.u = ~m.u + ((n.l ^ m.l) & Fix24_msb ? 0 : Fix24_lsb);
  464.   return Fix48(n);
  465. }
  466.  
  467. inline Fix48 operator*(long b, Fix48& a)     
  468.   return a * b; 
  469. }
  470.  
  471. inline Fix48& Fix48::operator+=(Fix48& f)     
  472.   return *this = *this + f;
  473. }
  474.  
  475. inline Fix48& Fix48::operator-=(Fix48& f)     
  476.   return *this = *this - f;
  477. }
  478.  
  479. inline Fix48& Fix48::operator*=(long b)    
  480.   return *this = *this * b;
  481. }
  482.  
  483. inline Fix48& Fix48::operator<<=(int b)    
  484.   return *this = *this << b;
  485. }
  486.  
  487. inline Fix48& Fix48::operator>>=(int b)    
  488.   return *this = *this >> b;
  489. }
  490.  
  491. inline int operator==(Fix48& f, Fix48& g)    
  492.   return f.m.u == g.m.u && f.m.l == g.m.l;
  493. }
  494.  
  495. inline int operator!=(Fix48& f, Fix48& g)    
  496.   return f.m.u != g.m.u || f.m.l != g.m.l;
  497. }
  498.  
  499. inline int operator>=(Fix48& f, Fix48& g)    
  500.   return f.m.u >= g.m.u || (f.m.u == g.m.u && f.m.l >= g.m.l);
  501. }
  502.  
  503. inline int operator<=(Fix48& f, Fix48& g)    
  504.   return f.m.u <= g.m.u || (f.m.u == g.m.u && f.m.l <= g.m.l);
  505. }
  506.  
  507. inline int operator>(Fix48& f, Fix48& g)    
  508.   return f.m.u > g.m.u || (f.m.u == g.m.u && f.m.l > g.m.l);
  509. }
  510.  
  511. inline int operator<(Fix48& f, Fix48& g)    
  512.   return f.m.u < g.m.u || (f.m.u == g.m.u && f.m.l < g.m.l);
  513. }
  514.  
  515. inline istream& operator>>(istream& s, Fix48& f)
  516.   double d;
  517.   s >> d; 
  518.   f = d; 
  519.   return s; 
  520. }
  521.  
  522. inline ostream& operator<<(ostream& s, Fix48& f)
  523.   return s << double(f);
  524. }
  525.  
  526.  
  527. #endif
  528. #endif
  529.  
  530.