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