/*
 *  hrdarth.h from ObjectProDSP 0.2
 *  Copyright (C) 1994 1995, Mountain Math Software. All rights reserved.
 *  
 *  This file is part of ObjectProDSP, a tool for Digital Signal
 *  Processing design, development and implementation. It is free
 *  software provided you use and distribute it under the terms of
 *  version 2 of the GNU General Public License as published
 *  by the Free Software Foundation. You may NOT distribute it or
 *  works derived from it or code that it generates under ANY
 *  OTHER terms.  In particular NONE of the ObjectProDSP system is
 *  licensed for use under the GNU General Public LIBRARY License.
 *  Mountain Math Software plans to offer a commercial version of
 *  ObjectProDSP for a fee. That version will allow redistribution
 *  of generated code under standard commercial terms.
 *  
 *  This program 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 General Public License for more details.
 *  
 *  You should have received a copy of version 2 of the GNU General
 *  Public License along with this program. See file COPYING. If not
 *  or if you wish information on commercial versions and licensing
 *  write Mountain Math Software, P. O. Box 2124, Saratoga, CA 95070,
 *  USA, or send us e-mail at: support@mtnmath.com.
 *  
 *  You may also obtain the GNU General Public License by writing the
 *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 *  USA.  However if you received a copy of this program without the
 *  file COPYING or without a copyright notice attached to all text
 *  files, libraries and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
/*  hrdarth.h   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */

// Class definitions for hardware arithmentic.
// The actual arithmetic functions are in "hrdcmp.h"
// so they do not to be included whenver size only information is needed.

#ifndef HRDARTH_DOT_H
#define HRDARTH_DOT_H
#include <values.h>

#ifndef OVERFLOW
#include <complex.h>
#endif 

#include "ObjProDSP/portable.h"
#include "ObjProDSP/arthtyp.h"

#define TheArithType ArithType::ArithFloat

class CxAccMachWord ;
class AccMachWord ;
class CxMachWord ;

#ifdef __NT_VC__
inline float real(complex cx) {return cx.x;}
inline float imag(complex cx) {return cx.y;}
complex NT_complex_multiply(complex&a, complex&b);
#define NT_complex(X,a,b) complex X; X.x =a; X.y =b ;
#else
#define NT_complex(X,a,b) complex X = complex(a,b);
#endif


typedef uint32 BinMachWord ;
typedef uint32 UnsignedIntegerMachWord ; // Use this, BinMachWord is obsolete

typedef int32 SignedBinMachWord ;
typedef int32 IntegerMachWord ; // use this SignedBinMachWord is obsolete

typedef float MachWordCast ;
typedef float AccMachWordCast ;

class MachWord{
friend AccMachWord;
friend inline double GetDoubleFromPtr(MachWord *);
friend complex GetComplexFromPtr(CxMachWord * v) ;
	float value;
public:
	// operator float() const ;
	operator float() const {return value;}
	MachWord(const MachWord& x) {value = x.value;}
	MachWord() {value = 0;}
	MachWord(float v) {value = v;} 
	MachWord(int v) {value = v;}
	MachWord(unsigned int v) {value = v;}
	MachWord(double v) ;
	float val() const {return value;}
	// MachWord operator-() const ;
	inline MachWord operator-() const {return MachWord(-value);}
	inline void operator+=(MachWord) ;
	inline void operator-=(MachWord) ;
	inline void operator*=(MachWord) ;
	inline void operator/=(MachWord) ;
	inline void operator|=(MachWord) ;
	inline void operator&=(MachWord) ;
	inline void operator^=(MachWord) ;
	inline void operator%=(MachWord) ;
	inline int operator<(MachWord) const ;
	inline int operator>(MachWord) const ;
	inline int operator<=(MachWord) const ;
	inline int operator>=(MachWord) const ;
	inline int operator==(MachWord) const ;
	inline int operator!=(MachWord) const ;
	inline void operator<<=(int) ;
	inline void operator>>=(int) ;
	static const float max_positive ;
	static const float min_negative ;
	static const int32 max_int_positive ;
	static const int32 min_int_negative ;
	static const uint32 max_unsigned_int ;
	static MachWordCast convert_MachWord_check(IntegerMachWord);
	static int32 convert_int32_check(MachWord v);
	static IntegerMachWord convert_check(MachWord v);
	static IntegerMachWord convert_int_check(int32);
	static UnsignedIntegerMachWord convert_unsigned_int_check(int32);
	static IntegerMachWord convert_int_check(double);
	static UnsignedIntegerMachWord convert_unsigned_int_check(double);
	static void hard_limit_warn(const char * type = "MachWord");
};

inline double GetDoubleFromPtr(MachWord *Ptr) { return (double) Ptr->value;}

class AccMachWord {
friend inline double GetDoubleFromPtr(AccMachWord *);
friend complex GetComplexFromPtr(CxAccMachWord * v) ;
	float value;
public:
	operator float() const { return value;}
	// operator float() const ;
	AccMachWord(MachWord v)  {value = v.value;}
	AccMachWord() {value = 0.0;}
	AccMachWord(const AccMachWord& v) {value = v.value;}
	// AccMachWord(float v=0) {value=v;}
	AccMachWord(double v) {value = v;}
	// AccMachWord operator-() const ;
	AccMachWord operator-() const {return AccMachWord(-value);}
	float val() const {return value;}
	// void operator=(AccMachWord val) {value = val;}
	inline void operator+=(AccMachWord);
	inline void operator-=(AccMachWord);
	inline void operator*=(AccMachWord);
	inline void operator/=(AccMachWord);
	inline int operator<(AccMachWord) const ;
	inline int operator>(AccMachWord) const ;
	inline int operator<=(AccMachWord) const ;
	inline int operator>=(AccMachWord) const ;
	inline int operator==(AccMachWord) const ;
	inline int operator!=(AccMachWord) const ;
	static const double max_positive ;
    static const double min_negative ;

};
inline double GetDoubleFromPtr(AccMachWord *Ptr) { return (double) Ptr->value;}

inline MachWord MachReal(const CxMachWord& a);
inline MachWord MachImag(const CxMachWord& a);

class CxMachWord{
friend complex GetComplexFromPtr(CxMachWord * v) ;
	MachWord rl;
	MachWord ig;
public:
	CxMachWord(MachWord r, MachWord i) ;
	CxMachWord(MachWord r) ;
	CxMachWord(float r=0,float i=0);
	CxMachWord(const CxMachWord& x);
	CxMachWord(const complex& cx);
	CxMachWord operator-() const {return CxMachWord(-rl,-ig);}
	// void operator=(CxMachWord v) {rl =MachReal(v); ig = MachImag(v);}
	void operator+=(const CxMachWord&);
	void operator-=(const CxMachWord&);
	void operator*=(const CxMachWord&);
	void operator*=(MachWord);
	void operator/=(const CxMachWord&);
	void operator/=(MachWord);
	operator complex() const ;
	friend MachWord MachReal(const CxMachWord&);
	friend MachWord MachImag(const CxMachWord&);
	friend CxMachWord conj (const CxMachWord&);
};

inline CxMachWord conj(const CxMachWord& arg)
{
	return CxMachWord(arg.rl, -arg.ig);
}


inline MachWord MachReal(const CxMachWord& a)
{
	return a.rl;
}

inline MachWord MachImag(const CxMachWord& a)
{
	return a.ig;
}

class CxAccMachWord ;
inline AccMachWord MachReal(const CxAccMachWord& );
inline AccMachWord MachImag(const CxAccMachWord& );

class CxAccMachWord {
friend complex GetComplexFromPtr(CxAccMachWord * v) ;
	AccMachWord Real;
	AccMachWord Imag;
public:
	CxAccMachWord(float r=0,float i=0) ;
	CxAccMachWord(const CxMachWord& W) ;
	CxAccMachWord(const CxAccMachWord& W) ;
	CxAccMachWord(AccMachWord R, AccMachWord I) ;
	CxAccMachWord(MachWord R,MachWord I) ;
	CxAccMachWord operator-() const {return CxAccMachWord(-Real,-Imag);}
	// void operator=(CxAccMachWord v)
	//	{Real = MachReal(v) ; Imag = MachImag(v);}
	void operator+=(const CxAccMachWord&);
	void operator-=(const CxAccMachWord&);
	void operator*=(const CxAccMachWord&);
	void operator*=(AccMachWord);
	void operator/=(const CxAccMachWord&);
	void operator/=(AccMachWord);
	void operator|=(const CxAccMachWord&);
	void operator&=(const CxAccMachWord&);
	void operator^=(const CxAccMachWord&);
	void operator%=(const CxAccMachWord&);
	void operator<<=(int) ;
	void operator>>=(int) ;
	operator complex() const ;
	friend AccMachWord MachReal(const CxAccMachWord& );
	friend AccMachWord MachImag(const CxAccMachWord& );
	friend CxAccMachWord conj (const CxAccMachWord& );
};

inline CxAccMachWord conj(const CxAccMachWord& arg)
{
	return CxAccMachWord(arg.Real, -arg.Imag);
}

inline AccMachWord MachReal(const CxAccMachWord& a)
{
	return a.Real ;
}

inline AccMachWord MachImag(const CxAccMachWord& a)
{
	return a.Imag ;
}

struct CxAccMachWordType {
	float r;
	float i;
} ; 			// Used to initalize arrays of 'CxAccMachWords'

struct CxMachWordType {
	float r;
	float i;
} ; 			// Used to initalize arrays of 'CxMachWords'

typedef float AccMachWordType ;
typedef float MachWordType ;

/*
 * struct AccMachWordType {
 * 	float v;
 * } ; 			// Used to initalize arrays of 'AccMachWords'
 * 
 * struct MachWordType {
 * float v;
 * } ; 			// Used to initalize arrays of 'MachWords'
*/


complex GetComplexFromPtr(MachWord * v) ;
complex GetComplexFromPtr(AccMachWord * v);


#ifdef __NT_VC__
#define MAXFLOAT FLT_MAX
#include <float.h>
#endif
#define DEF_MACH_WORD_MAX  MAXFLOAT
#define DEF_MACH_WORD_MIN -DEF_MACH_WORD_MAX-1
#define DEF_ACC_MACH_WORD_MAX  MAXFLOAT
#define DEF_ACC_MACH_WORD_MIN -DEF_ACC_MACH_WORD_MAX-1
#define FLOAT_MACH_WORD_TYPE

#define NormToOneMachWord 1.

typedef double OverflowCheck ;
extern MachWord check_overflow(double test_val,int32& number_overflows);
extern AccMachWord check_overflow_acc(double test_val,int32& number_overflows);

 
extern MachWord NormToMachWord(double v);
extern AccMachWord NormToAccMachWord(double v);
// these routines give warnings the following two do not and are
// usable in static initializers
extern MachWord NormToHardLimitMachWord(double v);
extern AccMachWord NormToHardLimitAccMachWord(double v);

extern double NormFromMachWord(double val) ;
extern double NormFromAccMachWord(double val) ;


#endif /* #ifdef HRDARTH_DOT_H */

