home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / g__inc / xfix16.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-23  |  12.5 KB  |  643 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 _Fix16_h
  21. #ifdef __GNUG__
  22. #pragma once
  23. #pragma interface
  24. #endif
  25. #define _Fix16_h 1
  26.  
  27. #include <stream.h>
  28. #include <std.h>
  29.  
  30. // constant definitions
  31.  
  32. #define Fix16_fs     ((double)((unsigned)(1 << 15)))
  33.  
  34. #define Fix16_msb    (1 << 15)
  35. #define Fix16_m_max    ((1 << 15) - 1)
  36. #define Fix16_m_min    ((short)(1 << 15))
  37.  
  38. #define Fix16_mult    Fix16_fs
  39. #define Fix16_div    (1./Fix16_fs)
  40. #define Fix16_max    (1. - .5/Fix16_fs)
  41. #define Fix16_min    (-1.)
  42.  
  43.  
  44. #define Fix32_fs     ((double)((unsigned long)(1 << 31)))
  45.  
  46. #define Fix32_msb    ((unsigned long)(1 << 31))
  47. #define Fix32_m_max    ((long)((1L << 31) - 1L))
  48. #define Fix32_m_min    ((long)(1 << 31))
  49.  
  50. #define Fix32_mult    Fix32_fs
  51. #define Fix32_div    (1./Fix32_fs)
  52. #define Fix32_max    (1. - .5/Fix32_fs)
  53. #define Fix32_min    (-1.)
  54.  
  55.  
  56. //
  57. // Fix16    class: 16-bit Fixed point data type
  58. //
  59. //    consists of a 16-bit mantissa (sign bit & 15 data bits).
  60. //
  61.  
  62. class Fix16 
  63.   friend class          Fix32;
  64.  
  65.   short                 m;
  66.  
  67.   short                 round(double d);
  68.   short                 assign(double d);
  69.                         Fix16(short i);
  70.                         Fix16(int i);
  71.  
  72.          operator       double();
  73.  
  74.  
  75. public:
  76.                         Fix16();
  77.                         Fix16(Fix16&  f);
  78.                         Fix16(double d);
  79.                         Fix16(Fix32& f);
  80.  
  81.                         ~Fix16();
  82.  
  83.   Fix16&                operator=(Fix16&  f);
  84.   Fix16&                operator=(double d);
  85.   Fix16&                operator=(Fix32& f);
  86.  
  87.   friend short&         mantissa(Fix16&  f);
  88.   friend double         value(Fix16&  f);
  89.  
  90.   Fix16                 operator +  ();
  91.   Fix16                 operator -  ();
  92.  
  93.   friend Fix16          operator +  (Fix16&  f, Fix16&  g);
  94.   friend Fix16          operator -  (Fix16&  f, Fix16&  g);
  95.   friend Fix32          operator *  (Fix16&  f, Fix16&  g);
  96.   friend Fix16          operator /  (Fix16&  f, Fix16&  g);
  97.   friend Fix16          operator << (Fix16&  f, int b);
  98.   friend Fix16          operator >> (Fix16&  f, int b);
  99.  
  100.   Fix16&                operator += (Fix16&  f);
  101.   Fix16&                operator -= (Fix16&  f);
  102.   Fix16&                operator *= (Fix16& );
  103.   Fix16&                operator /= (Fix16&  f);
  104.   
  105.   Fix16&                operator <<=(int b);
  106.   Fix16&                operator >>=(int b);
  107.  
  108.   friend int            operator == (Fix16&  f, Fix16&  g);
  109.   friend int            operator != (Fix16&  f, Fix16&  g);
  110.   friend int            operator >= (Fix16&  f, Fix16&  g);
  111.   friend int            operator <= (Fix16&  f, Fix16&  g);
  112.   friend int            operator >  (Fix16&  f, Fix16&  g);
  113.   friend int            operator <  (Fix16&  f, Fix16&  g);
  114.  
  115.   friend istream&       operator >> (istream& s, Fix16&  f);
  116.   friend ostream&       operator << (ostream& s, Fix16&  f);
  117.  
  118.   void                  overflow(short&);
  119.   void                  range_error(short&);
  120.  
  121.   friend Fix16          operator *  (Fix16&  f, int g);
  122.   friend Fix16          operator *  (int g, Fix16&  f);
  123.   Fix16&                operator *= (int g);
  124. };
  125.  
  126.  
  127. //
  128. // Fix32 class: 32-bit Fixed point data type
  129. //
  130. //    consists of a 32-bit mantissa (sign bit & 31 data bits).
  131. //
  132.  
  133. class Fix32 
  134.   friend class         Fix16;
  135.  
  136.   long                 m;
  137.  
  138.   long                 round(double d);
  139.   long                 assign(double d);
  140.  
  141.                        Fix32(long i);
  142.                        operator double();
  143.  
  144.  
  145. public:
  146.                        Fix32();
  147.                        Fix32(Fix32& f);
  148.                        Fix32(Fix16&  f);
  149.                        Fix32(double d);
  150.                        ~Fix32();
  151.  
  152.   Fix32&               operator =  (Fix32& f);
  153.   Fix32&               operator =  (Fix16&  f);
  154.   Fix32&               operator =  (double d);
  155.  
  156.   friend long&         mantissa(Fix32& f);
  157.   friend double        value(Fix32& f);
  158.  
  159.   Fix32                operator +  ();
  160.   Fix32                operator -  ();
  161.  
  162.   friend Fix32         operator +  (Fix32& f, Fix32& g);
  163.   friend Fix32         operator -  (Fix32& f, Fix32& g);
  164.   friend Fix32         operator *  (Fix32& f, Fix32& g);
  165.   friend Fix32         operator /  (Fix32& f, Fix32& g);
  166.   friend Fix32         operator << (Fix32& f, int b);
  167.   friend Fix32         operator >> (Fix32& f, int b);
  168.  
  169.   friend Fix32         operator *  (Fix16&  f, Fix16&  g);
  170.  
  171.   Fix32&               operator += (Fix32& f);
  172.   Fix32&               operator -= (Fix32& f);
  173.   Fix32&               operator *= (Fix32& f);
  174.   Fix32&               operator /= (Fix32& f);
  175.   Fix32&               operator <<=(int b);
  176.   Fix32&               operator >>=(int b);
  177.  
  178.   friend int           operator == (Fix32& f, Fix32& g);
  179.   friend int           operator != (Fix32& f, Fix32& g);
  180.   friend int           operator >= (Fix32& f, Fix32& g);
  181.   friend int           operator <= (Fix32& f, Fix32& g);
  182.   friend int           operator >  (Fix32& f, Fix32& g);
  183.   friend int           operator <  (Fix32& f, Fix32& g);
  184.  
  185.   friend istream&      operator >> (istream& s, Fix32& f);
  186.   friend ostream&      operator << (ostream& s, Fix32& f);
  187.  
  188.   void                 overflow(long& i);
  189.   void                 range_error(long& i);
  190.  
  191.   friend Fix32          operator *  (Fix32&  f, long g);
  192.   friend Fix32          operator *  (long g, Fix32&  f);
  193.   Fix32&                operator *= (long g);
  194. };
  195.  
  196. // active error handler declarations
  197.  
  198. typedef void (*Fix16_peh)(short&);
  199. typedef void (*Fix32_peh)(long&);
  200.  
  201. extern Fix16_peh Fix16_overflow_handler;
  202. extern Fix32_peh Fix32_overflow_handler;
  203.  
  204. extern Fix16_peh Fix16_range_error_handler;
  205. extern Fix32_peh Fix32_range_error_handler;
  206.  
  207. #if defined(SHORT_NAMES) || defined(VMS)
  208. #define    set_overflow_handler    sohndl
  209. #define set_range_error_handler    srnghdl
  210. #endif
  211.  
  212.  
  213. // error handler declarations
  214.  
  215. extern Fix16_peh set_Fix16_overflow_handler(Fix16_peh);
  216. extern Fix32_peh set_Fix32_overflow_handler(Fix32_peh);
  217. extern void set_overflow_handler(Fix16_peh, Fix32_peh);
  218.  
  219. extern Fix16_peh set_Fix16_range_error_handler(Fix16_peh);
  220. extern Fix32_peh set_Fix32_range_error_handler(Fix32_peh);
  221. extern void set_range_error_handler(Fix16_peh, Fix32_peh);
  222.  
  223. extern void
  224.   Fix16_ignore(short&),
  225.   Fix16_overflow_saturate(short&),
  226.   Fix16_overflow_warning_saturate(short&),
  227.   Fix16_warning(short&),
  228.   Fix16_abort(short&);
  229.  
  230. extern void
  231.   Fix32_ignore(long&),
  232.   Fix32_overflow_saturate(long&),
  233.   Fix32_overflow_warning_saturate(long&),
  234.   Fix32_warning(long&),
  235.   Fix32_abort(long&);
  236.  
  237. #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
  238.  
  239. inline Fix16::~Fix16() {}
  240.  
  241. inline short Fix16::round(double d)
  242.   return short( (d >= 0)? d + 0.5 : d - 0.5); 
  243. }
  244.  
  245. inline Fix16::Fix16(short i)        
  246.   m = i; 
  247. }
  248.  
  249. inline Fix16::Fix16(int i)        
  250.   m = i; 
  251. }
  252.  
  253. inline Fix16::operator double() 
  254.   return  Fix16_div * m; 
  255. }
  256.  
  257. inline Fix16::Fix16()                 
  258.   m = 0; 
  259. }
  260.  
  261. inline Fix16::Fix16(Fix16&  f)        
  262.   m = f.m; 
  263. }
  264.  
  265. inline Fix16::Fix16(double d)        
  266. {
  267.   m = assign(d);
  268. }
  269.  
  270.  
  271. inline Fix16&  Fix16::operator=(Fix16&  f)    
  272.   m = f.m; 
  273.   return *this; 
  274. }
  275.  
  276. inline Fix16&  Fix16::operator=(double d) 
  277.   m = assign(d); 
  278.   return *this; 
  279. }
  280.  
  281.  
  282. inline Fix32::Fix32()                
  283.   m = 0;
  284. }
  285.  
  286. inline Fix32::Fix32(long i)        
  287.   m = i;
  288. }
  289.  
  290. inline Fix32:: operator double()        
  291.   return Fix32_div * m;
  292. }
  293.  
  294.  
  295. inline Fix32::Fix32(Fix32& f)        
  296.   m = f.m;
  297. }
  298.  
  299. inline Fix32::Fix32(Fix16&  f)    
  300.   m = long(f.m) << 16;
  301. }
  302.  
  303. inline Fix32::Fix32(double d)        
  304.   m = assign(d);
  305. }
  306.  
  307. inline Fix16::Fix16(Fix32& f)        
  308.   m = f.m >> 16; 
  309. }
  310.  
  311.  
  312. inline Fix16&  Fix16::operator=(Fix32& f)
  313.   m = f.m >> 16; 
  314.   return *this; 
  315. }
  316.  
  317. inline Fix32& Fix32::operator=(Fix32& f)    
  318.   m = f.m;
  319.   return *this; 
  320. }
  321.  
  322. inline Fix32& Fix32::operator=(Fix16&  f)    
  323.   m = long(f.m) << 16;
  324.   return *this;
  325. }
  326.  
  327. inline Fix32& Fix32::operator=(double d)    
  328.   m = assign(d);
  329.   return *this; 
  330. }
  331.  
  332. inline short& mantissa(Fix16&  f)    
  333.   return f.m; 
  334. }
  335.  
  336. inline double value(Fix16&  f)        
  337.   return double(f); 
  338. }
  339.  
  340. inline Fix16 Fix16::operator+()         
  341.   return m; 
  342. }
  343.  
  344. inline Fix16 Fix16::operator-()         
  345.   return -m; 
  346. }
  347.  
  348. inline Fix16 operator+(Fix16&  f, Fix16&  g) 
  349. {
  350.   short sum = f.m + g.m;
  351.   if ( (f.m ^ sum) & (g.m ^ sum) & Fix16_msb )
  352.     f.overflow(sum);
  353.   return sum;
  354. }
  355.  
  356. inline Fix16 operator-(Fix16&  f, Fix16&  g) 
  357. {
  358.   short sum = f.m - g.m;
  359.   if ( (f.m ^ sum) & (-g.m ^ sum) & Fix16_msb )
  360.     f.overflow(sum);
  361.   return sum;
  362. }
  363.  
  364. inline Fix32 operator*(Fix16&  f, Fix16&  g)
  365.   return Fix32( long( long(f.m) * long(g.m) << 1)); 
  366. }
  367.  
  368. inline Fix16 operator<<(Fix16& a, int b)     
  369.   return a.m << b; 
  370. }
  371.  
  372. inline Fix16 operator>>(Fix16& a, int b)     
  373.   return a.m >> b; 
  374. }
  375.  
  376. inline  Fix16&  Fix16:: operator+=(Fix16&  f)
  377.   return *this = *this + f; 
  378. }
  379.  
  380. inline Fix16&  Fix16:: operator-=(Fix16&  f)     
  381.   return *this = *this - f; 
  382. }
  383.  
  384. inline Fix16& Fix16::operator*=(Fix16& f)     
  385.   return *this = *this * f; 
  386. }
  387.  
  388. inline Fix16&  Fix16:: operator/=(Fix16&  f)     
  389.   return *this = *this / f; 
  390. }
  391.  
  392. inline Fix16&  Fix16:: operator<<=(int b)    
  393.   return *this = *this << b;
  394. }
  395.  
  396. inline Fix16&  Fix16:: operator>>=(int b)    
  397.   return *this = *this >> b;
  398. }
  399.  
  400. inline int operator==(Fix16&  f, Fix16&  g)    
  401.   return f.m == g.m;
  402. }
  403.  
  404. inline int operator!=(Fix16&  f, Fix16&  g)    
  405.   return f.m != g.m;
  406. }
  407.  
  408. inline int operator>=(Fix16&  f, Fix16&  g)    
  409.   return f.m >= g.m;
  410. }
  411.  
  412. inline int operator<=(Fix16&  f, Fix16&  g)    
  413.   return f.m <= g.m;
  414. }
  415.  
  416. inline int operator>(Fix16&  f, Fix16&  g)    
  417.   return f.m > g.m;
  418. }
  419.  
  420. inline int operator<(Fix16&  f, Fix16&  g)    
  421.   return f.m < g.m;
  422. }
  423.  
  424. inline istream&  operator>>(istream& s, Fix16&  f)
  425.   double d;
  426.   s >> d; 
  427.   f = d; 
  428.   return s; 
  429. }
  430.  
  431. inline ostream&  operator<<(ostream& s, Fix16&  f)
  432.   return s << double(f);
  433. }
  434.  
  435.  
  436. inline Fix16 operator*(Fix16&  f, int g)
  437. {
  438.   return Fix16(short(f.m * g));
  439. }
  440.  
  441. inline Fix16 operator*(int g, Fix16&  f)
  442. {
  443.   return f * g;
  444. }
  445.  
  446.  
  447. inline Fix16& Fix16::operator*=(int g)
  448. {
  449.   return *this = *this * g;
  450. }
  451.  
  452. inline Fix32::~Fix32() {}
  453.  
  454. inline long Fix32::round(double d)
  455.   return long( (d >= 0)? d + 0.5 : d - 0.5);
  456. }
  457.  
  458.  
  459. inline long& mantissa(Fix32& f)    
  460.   return f.m;
  461. }
  462.  
  463. inline double value(Fix32& f)        
  464.   return double(f);
  465. }
  466.  
  467. inline Fix32 Fix32::operator+()         
  468.   return m;
  469. }
  470.  
  471. inline Fix32 Fix32::operator-()         
  472.   return -m;
  473. }
  474.  
  475. inline Fix32 operator+(Fix32& f, Fix32& g) 
  476. {
  477.   long sum = f.m + g.m;
  478.   if ( (f.m ^ sum) & (g.m ^ sum) & Fix32_msb )
  479.     f.overflow(sum);
  480.   return sum;
  481. }
  482.  
  483. inline Fix32 operator-(Fix32& f, Fix32& g) 
  484. {
  485.   long sum = f.m - g.m;
  486.   if ( (f.m ^ sum) & (-g.m ^ sum) & Fix32_msb )
  487.     f.overflow(sum);
  488.   return sum;
  489. }
  490.  
  491. inline Fix32 operator<<(Fix32& a, int b)     
  492.   return a.m << b;
  493. }
  494.  
  495. inline Fix32 operator>>(Fix32& a, int b)     
  496.   return a.m >> b;
  497. }
  498.  
  499. inline Fix32& Fix32::operator+=(Fix32& f)     
  500.   return *this = *this + f;
  501. }
  502.  
  503. inline Fix32& Fix32::operator-=(Fix32& f)     
  504.   return *this = *this - f;
  505. }
  506.  
  507. inline Fix32& Fix32::operator*=(Fix32& f)     
  508.   return *this = *this * f;
  509. }
  510.  
  511. inline Fix32& Fix32::operator/=(Fix32& f)     
  512.   return *this = *this / f;
  513. }
  514.  
  515.  
  516. inline Fix32& Fix32::operator<<=(int b)    
  517.   return *this = *this << b;
  518. }
  519.  
  520. inline Fix32& Fix32::operator>>=(int b)    
  521.   return *this = *this >> b;
  522. }
  523.  
  524. inline int operator==(Fix32& f, Fix32& g)    
  525.   return f.m == g.m;
  526. }
  527.  
  528. inline int operator!=(Fix32& f, Fix32& g)    
  529.   return f.m != g.m;
  530. }
  531.  
  532. inline int operator>=(Fix32& f, Fix32& g)    
  533.   return f.m >= g.m;
  534. }
  535.  
  536. inline int operator<=(Fix32& f, Fix32& g)    
  537.   return f.m <= g.m;
  538. }
  539.  
  540. inline int operator>(Fix32& f, Fix32& g)    
  541.   return f.m > g.m;
  542. }
  543.  
  544. inline int operator<(Fix32& f, Fix32& g)    
  545.   return f.m < g.m;
  546. }
  547.  
  548. inline istream& operator>>(istream& s, Fix32& f)
  549.   double d;
  550.   s >> d; 
  551.   f = d; 
  552.   return s; 
  553. }
  554.  
  555. inline ostream& operator<<(ostream& s, Fix32& f)
  556.   return s << double(f);
  557. }
  558.  
  559. inline Fix32 operator*(Fix32&  f, long g)
  560. {
  561.   return Fix32(long(f.m * g));
  562. }
  563.  
  564. inline Fix32 operator*(long g, Fix32&  f)
  565. {
  566.   return f * g;
  567. }
  568.  
  569.  
  570.  
  571. inline Fix32& Fix32::operator*=(long g)
  572. {
  573.   return *this = *this * g;
  574. }
  575.  
  576.  
  577. #endif
  578. #endif
  579.  
  580.