/*
**  CXSC is a C++ library for eXtended Scientific Computing
**
**  Copyright (C) 1990-2000 Institut fuer Angewandte Mathematik,
**                          Universitaet Karlsruhe, Germany
**            (C) 2000-2001 Wiss. Rechnen/Softwaretechnologie
**                          Universitaet Wuppertal, Germany   
**
**  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
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/* CVS $Id: real.hpp,v 1.3 2001/08/09 11:37:59 cxsc Exp $ */

#ifndef real_hpp_included
#define real_hpp_included

#include <iostream>
#include <string>

// namespace cxsc {

#include "compiler.h"
#include "RtsTyp.h"
#include "ioflags.hpp"

#include "except.hpp"

namespace cxsc {

class rvector;
class rmatrix;
class rvector_slice;
class rmatrix_slice;

#define  addu  addup
#define  addd  adddown
#define  subu  subup
#define  subd  subdown
#define  mulu  multup
#define  muld  multdown
#define  divu  divup
#define  divd  divdown

class real
{
   private:
      // ---- private data ----------------------------------------
      double w;

   public:
      // ---- implicit constructors -------------------------------
      real(void)  throw ()                  { }
      real(const float  &a) throw () : w(a) { }
      real(const double &a) throw () : w(a) { }
      real(const int     a) throw () : w(a) { }
      real(const long    a) throw () : w(a) { }

      // ---- explicit constructors -------------------------------

      explicit real(const l_real &) throw();

      // The following are defined in the specific vector, matrix-files
#if(IndCheck) 
		explicit INLINE real(const rvector &)       throw (ERROR_RVECTOR_TYPE_CAST_OF_THICK_OBJ,ERROR_RVECTOR_USE_OF_UNINITIALIZED_OBJ);
      explicit INLINE real(const rvector_slice &) throw (ERROR_RVECTOR_TYPE_CAST_OF_THICK_OBJ,ERROR_RVECTOR_USE_OF_UNINITIALIZED_OBJ);
      explicit INLINE real(const rmatrix &)       throw (ERROR_RMATRIX_TYPE_CAST_OF_THICK_OBJ,ERROR_RMATRIX_USE_OF_UNINITIALIZED_OBJ);
      explicit INLINE real(const rmatrix_slice &) throw (ERROR_RMATRIX_TYPE_CAST_OF_THICK_OBJ,ERROR_RMATRIX_USE_OF_UNINITIALIZED_OBJ);
#else
		explicit INLINE real(const rvector &)       throw ();
      explicit INLINE real(const rvector_slice &) throw ();
      explicit INLINE real(const rmatrix &)       throw ();
      explicit INLINE real(const rmatrix_slice &) throw ();
#endif

      // ---- assignments -----------------------------------------

      // ---- compatibility typecasts -----------------------------

      friend inline double _double(const real &a) throw() { return a.w; }
      friend inline real   _real(const double &a) throw() { return real(a); }

#if(IndCheck) 
      friend INLINE real _real(const rvector &)       throw (ERROR_RVECTOR_TYPE_CAST_OF_THICK_OBJ,ERROR_RVECTOR_USE_OF_UNINITIALIZED_OBJ);
      friend INLINE real _real(const rvector_slice &) throw (ERROR_RVECTOR_TYPE_CAST_OF_THICK_OBJ,ERROR_RVECTOR_USE_OF_UNINITIALIZED_OBJ);
      friend INLINE real _real(const rmatrix &)       throw (ERROR_RMATRIX_TYPE_CAST_OF_THICK_OBJ,ERROR_RMATRIX_USE_OF_UNINITIALIZED_OBJ);
      friend INLINE real _real(const rmatrix_slice &) throw (ERROR_RMATRIX_TYPE_CAST_OF_THICK_OBJ,ERROR_RMATRIX_USE_OF_UNINITIALIZED_OBJ);
#else
      friend INLINE real _real(const rvector &)       throw ();
      friend INLINE real _real(const rvector_slice &) throw ();
      friend INLINE real _real(const rmatrix &)       throw ();
      friend INLINE real _real(const rmatrix_slice &) throw ();
#endif
      
      // ---- Input/Output  ---------------------------------------

      friend std::ostream & operator <<(std::ostream &,const real &) throw();
      friend std::istream & operator >>(std::istream &,real &)       throw();
      friend std::string &  operator <<(std::string &,const real &)  throw();
      friend std::string &  operator >>(std::string &,real &)        throw();
      friend void           operator >>(const char *,real &)         throw();
      friend void           operator >>(const std::string &,real &)  throw();

      // ---- Std.Operators ---------------------------------------
      // As the real-arithmetic should be as fast as double all
      // operators are inlined.                

      friend real operator -(const real &) throw ();
      friend inline real operator +(const real &) throw ();

      friend inline real operator +(const real &,const real &) throw();
      friend inline real operator -(const real &,const real &) throw();
      friend inline real operator *(const real &,const real &) throw();
      friend inline real operator /(const real &,const real &) throw();

      friend inline real& operator +=(real &, const real &) throw();
      friend inline real& operator -=(real &, const real &) throw();
      friend inline real& operator *=(real &, const real &) throw();
      friend inline real& operator /=(real &, const real &) throw();

      // ---- Comp.Operat.  ---------------------------------------

      friend inline bool operator!  (const real& a)                throw();
      friend inline bool operator== (const real& a, const real& b) throw();
      friend inline bool operator!= (const real& a, const real& b) throw();
      friend inline bool operator<  (const real& a, const real& b) throw();
      friend inline bool operator<= (const real& a, const real& b) throw();
      friend inline bool operator>= (const real& a, const real& b) throw();
      friend inline bool operator>  (const real& a, const real& b) throw();

      friend inline bool operator== (const real& a, const int & b) throw();
      friend inline bool operator!= (const real& a, const int & b) throw();
      friend inline bool operator== (const int & a, const real& b) throw();
      friend inline bool operator!= (const int & a, const real& b) throw();
      friend inline bool operator== (const real& a, const long & b) throw();
      friend inline bool operator!= (const real& a, const long & b) throw();
      friend inline bool operator== (const long & a, const real& b) throw();
      friend inline bool operator!= (const long & a, const real& b) throw();
      friend inline bool operator== (const real& a, const float & b) throw();
      friend inline bool operator!= (const real& a, const float & b) throw();
      friend inline bool operator== (const float & a, const real& b) throw();
      friend inline bool operator!= (const float & a, const real& b) throw();
      friend inline bool operator== (const real& a, const double & b) throw();
      friend inline bool operator!= (const real& a, const double & b) throw();
      friend inline bool operator== (const double & a, const real& b) throw();
      friend inline bool operator!= (const double & a, const real& b) throw();
   
      // ---- Rounding Operators ---------------------------------

      friend  real addup(const real &, const real &);
      friend  real adddown(const real &, const real &);
      friend  real subup(const real &, const real &);
      friend  real subdown(const real &, const real &);
      friend  real multup(const real &, const real &);
      friend  real multdown(const real &, const real &);
      friend  real divup(const real &, const real &);
      friend  real divdown(const real &, const real &);

      // ---- Others   -------------------------------------------

      friend inline real abs(const real &) throw();
      friend inline int  sign(const real &) throw();
      
      friend inline real pred(const real &) throw();
      friend inline real succ(const real &) throw();
      friend inline a_intg expo(const real &) throw();
      friend inline real comp(const real &,a_intg i) throw();
      friend inline real mant(const real &) throw();
};

inline real max(const real & a, const real & b) { return a>b?a:b; }
inline real min(const real & a, const real & b) { return a<b?a:b; }

//----------------------------------------------------------------------
// MakeHexReal - erstellt aus den bin„r angegebenen Einzelteilen einer
//               IEEE 64-bit Gleitkommazahl eine solche

const real& MakeHexReal ( 
   int sign, unsigned int expo, a_btyp manthigh, a_btyp mantlow);

inline bool IsInfinity(const real &a);
inline bool IsQuietNan(const real &a);
inline bool IsSignalingNan(const real &a);


// ----  special constants -----------------------------------------
extern const real MinReal;    // kleinste normalisiert darstellbare
                              // Gleitkommazahl
extern const real MaxReal;    // gr”áte darstellbare Gleitkommazahl
extern const real Infinity;   // +Unendlich in Gleitkommadarstellung
extern const real SignalingNaN;// Undefiniertes Ergebnis in
                              // Gleitkommadarstellung
extern const real QuietNaN;   // ein 'Not a Number'

} // namespace cxsc 

#include "real.inl"

// }
#endif

