diff options
author | phk <phk@FreeBSD.org> | 1994-08-08 05:52:55 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1994-08-08 05:52:55 +0000 |
commit | c8beafaf61a7e1bf16aaef28f9112c7705f4f1f1 (patch) | |
tree | 45b379846d17cbe73053d37a6dc47dae07cdc33d /gnu/lib/libg++/include/Fix24.h | |
parent | 4c5e434fdaef40513ed9bc2059aa202f7e1b9929 (diff) | |
download | FreeBSD-src-c8beafaf61a7e1bf16aaef28f9112c7705f4f1f1.zip FreeBSD-src-c8beafaf61a7e1bf16aaef28f9112c7705f4f1f1.tar.gz |
I belive this should be makeable under 2.0. There may be outstanding
issues in these areas:
.h's installed
.hP's installed
-lcurses interaction
files needed in ~/legal for copyleft reasons.
Diffstat (limited to 'gnu/lib/libg++/include/Fix24.h')
-rw-r--r-- | gnu/lib/libg++/include/Fix24.h | 597 |
1 files changed, 597 insertions, 0 deletions
diff --git a/gnu/lib/libg++/include/Fix24.h b/gnu/lib/libg++/include/Fix24.h new file mode 100644 index 0000000..56d1191 --- /dev/null +++ b/gnu/lib/libg++/include/Fix24.h @@ -0,0 +1,597 @@ +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988 Free Software Foundation + written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu) + adapted for libg++ by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _Fix24_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _Fix24_h 1 + +#include <stream.h> +#include <std.h> + +// extra type definitions + +typedef struct { + long u; + unsigned long l; +} twolongs; + +// constant definitions + +static const int + Fix24_shift = 31; + +static const double + Fix24_fs = 2147483648., // 2^Fix24_shift + Fix24_mult = Fix24_fs, + Fix24_div = 1./Fix24_fs, + Fix24_max = 1. - .5/Fix24_fs, + Fix24_min = -1.; + +static const unsigned long + Fix24_msb = 0x80000000L, + Fix24_lsb = 0x00000100L, + Fix24_m_max = 0x7fffff00L, + Fix24_m_min = 0x80000000L; + +static const double + Fix48_fs = 36028797018963968., // 2^(24+Fix24_shift) + Fix48_max = 1. - .5/Fix48_fs, + Fix48_min = -1., + Fix48_div_u = 1./Fix24_fs, + Fix48_div_l = 1./Fix48_fs; + +static const twolongs + Fix48_msb = { 0x80000000L, 0L }, + Fix48_lsb = { 0L, 0x00000100L }, + Fix48_m_max = { 0x7fffff00L, 0xffffff00L }, + Fix48_m_min = { 0x80000000L, 0L }; + +// +// Fix24 class: 24-bit Fixed point data type +// +// consists of a 24-bit mantissa (sign bit & 23 data bits). +// + +class Fix24 +{ + friend class Fix48; + + long m; + + long assign(double d); + operator double() const; + Fix24(long i); + Fix24(int i); + + +public: + Fix24(); + Fix24(const Fix24& f); + Fix24(double d); + Fix24(const Fix48& f); + + ~Fix24(); + + Fix24& operator=(const Fix24& f); + Fix24& operator=(double d); + Fix24& operator=(const Fix48& f); + + friend long& mantissa(Fix24& f); + friend const long& mantissa(const Fix24& f); + friend double value(const Fix24& f); + + Fix24 operator + () const; + Fix24 operator - () const; + + friend Fix24 operator + (const Fix24& f, const Fix24& g); + friend Fix24 operator - (const Fix24& f, const Fix24& g); + friend Fix48 operator * (const Fix24& f, const Fix24& g); + friend Fix24 operator * (const Fix24& f, int g); + friend Fix24 operator * (int g, const Fix24& f); + friend Fix24 operator / (const Fix24& f, const Fix24& g); + friend Fix24 operator << (const Fix24& f, int b); + friend Fix24 operator >> (const Fix24& f, int b); + + Fix24& operator += (const Fix24& f); + Fix24& operator -= (const Fix24& f); + Fix24& operator *= (const Fix24& f); + Fix24& operator *= (int b); + Fix24& operator /= (const Fix24& f); + + Fix24& operator <<=(int b); + Fix24& operator >>=(int b); + + friend int operator == (const Fix24& f, const Fix24& g); + friend int operator != (const Fix24& f, const Fix24& g); + friend int operator >= (const Fix24& f, const Fix24& g); + friend int operator <= (const Fix24& f, const Fix24& g); + friend int operator > (const Fix24& f, const Fix24& g); + friend int operator < (const Fix24& f, const Fix24& g); + + friend istream& operator >> (istream& s, Fix24& f); + friend ostream& operator << (ostream& s, const Fix24& f); + + void overflow(long&) const; + void range_error(long&) const; +}; + + +// +// Fix48 class: 48-bit Fixed point data type +// +// consists of a 48-bit mantissa (sign bit & 47 data bits). +// + +class Fix48 +{ + friend class Fix24; + + twolongs m; + + twolongs assign(double d); + operator double() const; + Fix48(twolongs i); + +public: + Fix48(); + Fix48(const Fix48& f); + Fix48(const Fix24& f); + Fix48(double d); + ~Fix48(); + + Fix48& operator = (const Fix48& f); + Fix48& operator = (const Fix24& f); + Fix48& operator = (double d); + + friend twolongs& mantissa(Fix48& f); + friend const twolongs& mantissa(const Fix48& f); + friend double value(const Fix48& f); + + Fix48 operator + () const; + Fix48 operator - () const; + + friend Fix48 operator + (const Fix48& f, const Fix48& g); + friend Fix48 operator - (const Fix48& f, const Fix48& g); + friend Fix48 operator * (const Fix48& f, int g); + friend Fix48 operator * (int g, const Fix48& f); + friend Fix48 operator << (const Fix48& f, int b); + friend Fix48 operator >> (const Fix48& f, int b); + + friend Fix48 operator * (const Fix24& f, const Fix24& g); + + Fix48& operator += (const Fix48& f); + Fix48& operator -= (const Fix48& f); + Fix48& operator *= (int b); + Fix48& operator <<=(int b); + Fix48& operator >>=(int b); + + friend int operator == (const Fix48& f, const Fix48& g); + friend int operator != (const Fix48& f, const Fix48& g); + friend int operator >= (const Fix48& f, const Fix48& g); + friend int operator <= (const Fix48& f, const Fix48& g); + friend int operator > (const Fix48& f, const Fix48& g); + friend int operator < (const Fix48& f, const Fix48& g); + + friend istream& operator >> (istream& s, Fix48& f); + friend ostream& operator << (ostream& s, const Fix48& f); + + void overflow(twolongs& i) const; + void range_error(twolongs& i) const; +}; + + +// active error handler declarations + +typedef void (*Fix24_peh)(long&); +typedef void (*Fix48_peh)(twolongs&); + +extern Fix24_peh Fix24_overflow_handler; +extern Fix48_peh Fix48_overflow_handler; + +extern Fix24_peh Fix24_range_error_handler; +extern Fix48_peh Fix48_range_error_handler; + + +// error handler declarations + +#if defined(SHORT_NAMES) || defined(VMS) +#define set_overflow_handler sohndl +#define set_range_error_handler srnghdl +#endif + +extern Fix24_peh set_Fix24_overflow_handler(Fix24_peh); +extern Fix48_peh set_Fix48_overflow_handler(Fix48_peh); +extern void set_overflow_handler(Fix24_peh, Fix48_peh); + +extern Fix24_peh set_Fix24_range_error_handler(Fix24_peh); +extern Fix48_peh set_Fix48_range_error_handler(Fix48_peh); +extern void set_range_error_handler(Fix24_peh, Fix48_peh); + +extern void + Fix24_ignore(long&), + Fix24_overflow_saturate(long&), + Fix24_overflow_warning_saturate(long&), + Fix24_warning(long&), + Fix24_abort(long&); + +extern void + Fix48_ignore(twolongs&), + Fix48_overflow_saturate(twolongs&), + Fix48_overflow_warning_saturate(twolongs&), + Fix48_warning(twolongs&), + Fix48_abort(twolongs&); + + +inline Fix24::~Fix24() {} + +inline Fix24::Fix24(long i) +{ + m = i; +} + +inline Fix24::Fix24(int i) +{ + m = i; +} + +inline Fix24::operator double() const +{ + return Fix24_div * m; +} + +inline Fix24::Fix24() +{ + m = 0; +} + +inline Fix24::Fix24(const Fix24& f) +{ + m = f.m; +} + +inline Fix24::Fix24(double d) +{ + m = assign(d); +} + +inline Fix24::Fix24(const Fix48& f) +{ + m = f.m.u; +} + +inline Fix24& Fix24::operator=(const Fix24& f) +{ + m = f.m; + return *this; +} + +inline Fix24& Fix24::operator=(double d) +{ + m = assign(d); + return *this; +} + +inline Fix24& Fix24::operator=(const Fix48& f) +{ + m = f.m.u; + return *this; +} + +inline long& mantissa(Fix24& f) +{ + return f.m; +} + +inline const long& mantissa(const Fix24& f) +{ + return f.m; +} + +inline double value(const Fix24& f) +{ + return double(f); +} + +inline Fix24 Fix24::operator+() const +{ + return m; +} + +inline Fix24 Fix24::operator-() const +{ + return -m; +} + +inline Fix24 operator+(const Fix24& f, const Fix24& g) +{ + long sum = f.m + g.m; + if ( (f.m ^ sum) & (g.m ^ sum) & Fix24_msb ) + f.overflow(sum); + return sum; +} + +inline Fix24 operator-(const Fix24& f, const Fix24& g) +{ + long sum = f.m - g.m; + if ( (f.m ^ sum) & (-g.m ^ sum) & Fix24_msb ) + f.overflow(sum); + return sum; +} + +inline Fix24 operator*(const Fix24& a, int b) +{ + return a.m * b; +} + +inline Fix24 operator*(int b, const Fix24& a) +{ + return a * b; +} + +inline Fix24 operator<<(const Fix24& a, int b) +{ + return a.m << b; +} + +inline Fix24 operator>>(const Fix24& a, int b) +{ + return (a.m >> b) & (long)0xffffff00; +} + +inline Fix24& Fix24:: operator+=(const Fix24& f) +{ + return *this = *this + f; +} + +inline Fix24& Fix24:: operator-=(const Fix24& f) +{ + return *this = *this - f; +} + +inline Fix24& Fix24::operator*=(const Fix24& f) +{ + return *this = *this * f; +} + +inline Fix24& Fix24:: operator/=(const Fix24& f) +{ + return *this = *this / f; +} + +inline Fix24& Fix24:: operator<<=(int b) +{ + return *this = *this << b; +} + +inline Fix24& Fix24:: operator>>=(int b) +{ + return *this = *this >> b; +} + +inline Fix24& Fix24::operator*=(int b) +{ + return *this = *this * b; +} + +inline int operator==(const Fix24& f, const Fix24& g) +{ + return f.m == g.m; +} + +inline int operator!=(const Fix24& f, const Fix24& g) +{ + return f.m != g.m; +} + +inline int operator>=(const Fix24& f, const Fix24& g) +{ + return f.m >= g.m; +} + +inline int operator<=(const Fix24& f, const Fix24& g) +{ + return f.m <= g.m; +} + +inline int operator>(const Fix24& f, const Fix24& g) +{ + return f.m > g.m; +} + +inline int operator<(const Fix24& f, const Fix24& g) +{ + return f.m < g.m; +} + +inline istream& operator>>(istream& s, Fix24& f) +{ + double d; + s >> d; + f = d; + return s; +} + +inline ostream& operator<<(ostream& s, const Fix24& f) +{ + return s << double(f); +} + +inline Fix48::~Fix48() {} + +inline Fix48::Fix48(twolongs i) +{ + m = i; +} + +inline Fix48:: operator double() const +{ +/* + * Note: can't simply do Fix48_div_u * m.u + Fix48_div_l * m.l, because + * m.u is signed and m.l is unsigned. + */ + return (m.u >= 0)? Fix48_div_u * m.u + Fix48_div_l * m.l : + (Fix48_div_u * ((unsigned long)(m.u & 0xffffff00)) + + Fix48_div_l * m.l) - 2; +} + +inline Fix48::Fix48() +{ + m.u = 0; + m.l = 0; +} + +inline Fix48::Fix48(const Fix48& f) +{ + m = f.m; +} + +inline Fix48::Fix48(const Fix24& f) +{ + m.u = f.m; + m.l = 0; +} + +inline Fix48::Fix48(double d) +{ + m = assign(d); +} + +inline Fix48& Fix48::operator=(const Fix48& f) +{ + m = f.m; + return *this; +} + +inline Fix48& Fix48::operator=(const Fix24& f) +{ + m.u = f.m; + m.l = 0; + return *this; +} + +inline Fix48& Fix48::operator=(double d) +{ + m = assign(d); + return *this; +} + +inline twolongs& mantissa(Fix48& f) +{ + return f.m; +} + +inline const twolongs& mantissa(const Fix48& f) +{ + return f.m; +} + +inline double value(const Fix48& f) +{ + return double(f); +} + +inline Fix48 Fix48::operator+() const +{ + return m; +} + +inline Fix48 Fix48::operator-() const +{ + twolongs n; + n.l = -m.l; + n.u = ~m.u + ((n.l ^ m.l) & Fix24_msb ? 0 : Fix24_lsb); + return Fix48(n); +} + +inline Fix48 operator*(int b, const Fix48& a) +{ + return a * b; +} + +inline Fix48& Fix48::operator+=(const Fix48& f) +{ + return *this = *this + f; +} + +inline Fix48& Fix48::operator-=(const Fix48& f) +{ + return *this = *this - f; +} + +inline Fix48& Fix48::operator*=(int b) +{ + return *this = *this * b; +} + +inline Fix48& Fix48::operator<<=(int b) +{ + return *this = *this << b; +} + +inline Fix48& Fix48::operator>>=(int b) +{ + return *this = *this >> b; +} + +inline int operator==(const Fix48& f, const Fix48& g) +{ + return f.m.u == g.m.u && f.m.l == g.m.l; +} + +inline int operator!=(const Fix48& f, const Fix48& g) +{ + return f.m.u != g.m.u || f.m.l != g.m.l; +} + +inline int operator>=(const Fix48& f, const Fix48& g) +{ + return f.m.u >= g.m.u || (f.m.u == g.m.u && f.m.l >= g.m.l); +} + +inline int operator<=(const Fix48& f, const Fix48& g) +{ + return f.m.u <= g.m.u || (f.m.u == g.m.u && f.m.l <= g.m.l); +} + +inline int operator>(const Fix48& f, const Fix48& g) +{ + return f.m.u > g.m.u || (f.m.u == g.m.u && f.m.l > g.m.l); +} + +inline int operator<(const Fix48& f, const Fix48& g) +{ + return f.m.u < g.m.u || (f.m.u == g.m.u && f.m.l < g.m.l); +} + +inline istream& operator>>(istream& s, Fix48& f) +{ + double d; + s >> d; + f = d; + return s; +} + +inline ostream& operator<<(ostream& s, const Fix48& f) +{ + return s << double(f); +} + +#endif |